Skip to content

Commit

Permalink
Add 4 new functions: set_header_footer, set_page_layout, set_page_mar…
Browse files Browse the repository at this point in the history
…gins and set_panes

- Update unit tests and docs for the function
  • Loading branch information
xuri committed Dec 27, 2024
1 parent 8e22bff commit 2342461
Show file tree
Hide file tree
Showing 6 changed files with 470 additions and 18 deletions.
104 changes: 103 additions & 1 deletion excelize.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def load_lib():
lib = CDLL(os.path.join(os.path.dirname(__file__), load_lib()))
ENCODE = "utf-8"
__version__ = "0.0.2"
uppercase_words = ["id", "xml"]
uppercase_words = ["id", "sq", "xml"]


def py_to_base_ctype(py_value, c_type):
Expand Down Expand Up @@ -2182,6 +2182,108 @@ def set_defined_name(self, defined_name: DefinedName) -> Optional[Exception]:
err = lib.SetDefinedName(self.file_index, byref(options)).decode(ENCODE)
return None if err == "" else Exception(err)

def set_header_footer(
self, sheet: str, opts: HeaderFooterOptions
) -> Optional[Exception]:
"""
Set headers and footers by given worksheet name and the control
characters.
Args:
sheet (str): The worksheet name
opts (HeaderFooterOptions): The header footer options
Returns:
Optional[Exception]: Returns None if no error occurred,
otherwise returns an Exception with the message.
Example:
For example:
.. code-block:: python
err = f.set_header_footer(
"Sheet1",
excelize.HeaderFooterOptions(
different_first=True,
different_odd_even=True,
odd_header="&R&P",
odd_footer="&C&F",
even_header="&L&P",
even_footer="&L&D&R&T",
first_header="&CCenter &\"-,Bold\"Bold&\"-,Regular\"HeaderU+000A&D",
),
)
"""
lib.SetHeaderFooter.restype = c_char_p
options = py_value_to_c(opts, types_go._HeaderFooterOptions())
err = lib.SetHeaderFooter(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def set_page_layout(
self, sheet: str, opts: PageLayoutOptions
) -> Optional[Exception]:
"""
Sets worksheet page layout.
Args:
sheet (str): The worksheet name
opts (PageLayoutOptions): The page layout options
Returns:
Optional[Exception]: Returns None if no error occurred,
otherwise returns an Exception with the message.
"""
lib.SetPageLayout.restype = c_char_p
options = py_value_to_c(opts, types_go._PageLayoutOptions())
err = lib.SetPageLayout(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def set_page_margins(
self, sheet: str, opts: PageLayoutMarginsOptions
) -> Optional[Exception]:
"""
Set worksheet page margins.
Args:
sheet (str): The worksheet name
opts (PageLayoutMarginsOptions): The page margins options
Returns:
Optional[Exception]: Returns None if no error occurred,
otherwise returns an Exception with the message.
"""
lib.SetPageMargins.restype = c_char_p
options = py_value_to_c(opts, types_go._PageLayoutMarginsOptions())
err = lib.SetPageMargins(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def set_panes(self, sheet: str, opts: Panes) -> Optional[Exception]:
"""
Create and remove freeze panes and split panes by given worksheet name
and panes options.
Args:
sheet (str): The worksheet name
opts (Panes): The panes options
Returns:
Optional[Exception]: Returns None if no error occurred,
otherwise returns an Exception with the message.
"""
lib.SetPanes.restype = c_char_p
options = py_value_to_c(opts, types_go._Panes())
err = lib.SetPanes(
self.file_index, sheet.encode(ENCODE), byref(options)
).decode(ENCODE)
return None if err == "" else Exception(err)

def set_row_height(
self, sheet: str, row: int, height: float
) -> Optional[Exception]:
Expand Down
86 changes: 86 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ func cToGoArray(cArray reflect.Value, cArrayLen int) reflect.Value {
val := cArray.Interface().(*C.struct_RichTextRun)
arr := unsafe.Slice(val, cArrayLen)
return reflect.ValueOf(arr)
case "main._Ctype_struct_Selection":
val := cArray.Interface().(*C.struct_Selection)
arr := unsafe.Slice(val, cArrayLen)
return reflect.ValueOf(arr)
}
return cArray
}
Expand Down Expand Up @@ -1715,6 +1719,88 @@ func SetDefinedName(idx int, definedName *C.struct_DefinedName) *C.char {
return C.CString(errNil)
}

// SetHeaderFooter provides a function to set headers and footers by given
// worksheet name and the control characters.
//
//export SetHeaderFooter
func SetHeaderFooter(idx int, sheet *C.char, opts *C.struct_HeaderFooterOptions) *C.char {
var options excelize.HeaderFooterOptions
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.HeaderFooterOptions{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.HeaderFooterOptions)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).SetHeaderFooter(C.GoString(sheet), &options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// SetPageLayout provides a function to sets worksheet page layout.
//
//export SetPageLayout
func SetPageLayout(idx int, sheet *C.char, opts *C.struct_PageLayoutOptions) *C.char {
var options excelize.PageLayoutOptions
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.PageLayoutOptions{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.PageLayoutOptions)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).SetPageLayout(C.GoString(sheet), &options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// SetPageMargins provides a function to set worksheet page margins.
//
//export SetPageMargins
func SetPageMargins(idx int, sheet *C.char, opts *C.struct_PageLayoutMarginsOptions) *C.char {
var options excelize.PageLayoutMarginsOptions
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.PageLayoutMarginsOptions{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.PageLayoutMarginsOptions)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).SetPageMargins(C.GoString(sheet), &options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// SetPanes provides a function to create and remove freeze panes and split panes
// by given worksheet name and panes options.
//
//export SetPanes
func SetPanes(idx int, sheet *C.char, opts *C.struct_Panes) *C.char {
var options excelize.Panes
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.Panes{}))
if err != nil {
return C.CString(err.Error())
}
options = goVal.Elem().Interface().(excelize.Panes)
f, ok := files.Load(idx)
if !ok {
return C.CString(errFilePtr)
}
if err := f.(*excelize.File).SetPanes(C.GoString(sheet), &options); err != nil {
return C.CString(err.Error())
}
return C.CString(errNil)
}

// SetRowHeight provides a function to set the height of a single row. If the
// value of height is 0, will hide the specified row, if the value of height is
// -1, will unset the custom row height.
Expand Down
84 changes: 84 additions & 0 deletions test_excelize.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,90 @@ def test_add_form_control(self):
self.assertIsNone(f.save_as(os.path.join("test", "TestAddFormControl.xlsm")))
self.assertIsNone(f.close())

def test_header_footer(self):
f = excelize.new_file()
self.assertIsNone(
f.set_header_footer(
"Sheet1",
excelize.HeaderFooterOptions(
different_first=True,
different_odd_even=True,
odd_header="&R&P",
odd_footer="&C&F",
even_header="&L&P",
even_footer="&L&D&R&T",
first_header='&CCenter &"-,Bold"Bold&"-,Regular"HeaderU+000A&D',
),
)
)
self.assertIsNone(f.save_as(os.path.join("test", "TestHeaderFooter.xlsx")))
self.assertIsNone(f.close())

def test_page_layout(self):
f = excelize.new_file()
self.assertIsNone(
f.set_page_layout(
"Sheet1",
excelize.PageLayoutOptions(
size=1,
orientation="landscape",
first_page_number=1,
adjust_to=120,
fit_to_height=2,
fit_to_width=2,
black_and_white=True,
page_order="overThenDown",
),
)
)
self.assertIsNone(f.save_as(os.path.join("test", "TestPageLayout.xlsx")))
self.assertIsNone(f.close())

def test_page_margins(self):
f = excelize.new_file()
self.assertIsNone(
f.set_page_margins(
"Sheet1",
excelize.PageLayoutMarginsOptions(
bottom=1.0,
footer=1.0,
header=1.0,
left=1.0,
right=1.0,
top=1.0,
horizontally=True,
vertically=True,
),
)
)
self.assertIsNone(f.save_as(os.path.join("test", "TestPageMargins.xlsx")))
self.assertIsNone(f.close())

def test_panes(self):
f = excelize.new_file()
self.assertIsNone(
f.set_panes(
"Sheet1",
excelize.Panes(
freeze=True,
split=False,
x_split=1,
y_split=0,
top_left_cell="B1",
active_pane="topRight",
selection=[
excelize.Selection(
sq_ref="K16",
active_cell="K16",
pane="topRight",
)
],
),
)
)
self.assertIsNone(f.save_as(os.path.join("test", "TestPanes.xlsx")))
self.assertIsNone(f.close())

def test_pivot_table(self):
f = excelize.new_file()
month = [
Expand Down
Loading

0 comments on commit 2342461

Please sign in to comment.