Skip to content

Commit 5b8eb2e

Browse files
committed
Add 4 new stream mode functions: insert_page_break, merge_cell, set_col_width and set_panes
- Update unit tests and docs for the function
1 parent 4d0e021 commit 5b8eb2e

File tree

3 files changed

+189
-3
lines changed

3 files changed

+189
-3
lines changed

excelize.py

Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def load_lib():
8484

8585
lib = CDLL(os.path.join(os.path.dirname(__file__), load_lib()))
8686
ENCODE = "utf-8"
87-
__version__ = "0.0.2"
87+
__version__ = "0.0.3"
8888
uppercase_words = ["id", "rgb", "sq", "xml"]
8989

9090

@@ -474,6 +474,97 @@ def add_table(self, table: Table) -> Optional[Exception]:
474474
err = lib.StreamAddTable(self.sw_index, byref(options)).decode(ENCODE)
475475
return None if err == "" else Exception(err)
476476

477+
def insert_page_break(self, cell: str) -> Optional[Exception]:
478+
"""
479+
Creates a page break to determine where the printed page ends and where
480+
begins the next one by a given cell reference, the content before the
481+
page break will be printed on one page and after the page break on
482+
another.
483+
484+
Args:
485+
cell (str): The cell reference
486+
487+
Returns:
488+
Optional[Exception]: Returns None if no error occurred,
489+
otherwise returns an Exception with the message.
490+
"""
491+
lib.StreamInsertPageBreak.restype = c_char_p
492+
err = lib.StreamInsertPageBreak(self.sw_index, cell.encode(ENCODE)).decode(
493+
ENCODE
494+
)
495+
return None if err == "" else Exception(err)
496+
497+
def merge_cell(
498+
self, top_left_cell: str, bottom_right_cell: str
499+
) -> Optional[Exception]:
500+
"""
501+
Merge cells by a given range reference for the stream writer. Don't
502+
create a merged cell that overlaps with another existing merged cell.
503+
504+
Args:
505+
top_left_cell (str): The top-left cell reference
506+
bottom_right_cell (str): The right-bottom cell reference
507+
508+
Returns:
509+
Optional[Exception]: Returns None if no error occurred,
510+
otherwise returns an Exception with the message.
511+
"""
512+
lib.StreamMergeCell.restype = c_char_p
513+
err = lib.StreamMergeCell(
514+
self.sw_index,
515+
top_left_cell.encode(ENCODE),
516+
bottom_right_cell.encode(ENCODE),
517+
).decode(ENCODE)
518+
return None if err == "" else Exception(err)
519+
520+
def set_col_width(
521+
self, start_col: int, end_col: int, width: float
522+
) -> Optional[Exception]:
523+
"""
524+
Set the width of a single column or multiple columns for the stream
525+
writer. Note that you must call the 'set_col_width' function before the
526+
'set_row' function.
527+
528+
Args:
529+
start_col (int): The start column number
530+
end_col (int): The end column number
531+
width (float): The column width
532+
533+
Returns:
534+
Optional[Exception]: Returns None if no error occurred,
535+
otherwise returns an Exception with the message.
536+
537+
Example:
538+
For example set the width column B:C as 20:
539+
540+
.. code-block:: python
541+
542+
err = sw.set_col_width(2, 3, 20)
543+
"""
544+
lib.StreamSetColWidth.restype = c_char_p
545+
err = lib.StreamSetColWidth(
546+
self.sw_index, c_int(start_col), c_int(end_col), c_double(width)
547+
).decode(ENCODE)
548+
return None if err == "" else Exception(err)
549+
550+
def set_panes(self, opts: Panes) -> Optional[Exception]:
551+
"""
552+
Create and remove freeze panes and split panes by giving panes options
553+
for the stream writer. Note that you must call the 'set_panes' function
554+
before the 'set_row' function.
555+
556+
Args:
557+
opts (Panes): The panes options
558+
559+
Returns:
560+
Optional[Exception]: Returns None if no error occurred,
561+
otherwise returns an Exception with the message.
562+
"""
563+
lib.StreamSetPanes.restype = c_char_p
564+
options = py_value_to_c(opts, types_go._Panes())
565+
err = lib.StreamSetPanes(self.sw_index, byref(options)).decode(ENCODE)
566+
return None if err == "" else Exception(err)
567+
477568
def set_row(
478569
self,
479570
cell: str,
@@ -2477,7 +2568,7 @@ def set_col_width(
24772568
Args:
24782569
sheet (str): The worksheet name
24792570
start_col (str): The start column name
2480-
end_col (bool): The end column name
2571+
end_col (str): The end column name
24812572
width (float): The column width
24822573
24832574
Returns:

main.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,6 +1443,77 @@ func StreamAddTable(swIdx int, table *C.struct_Table) *C.char {
14431443
return C.CString(emptyString)
14441444
}
14451445

1446+
// StreamInsertPageBreak creates a page break to determine where the printed
1447+
// page ends and where begins the next one by a given cell reference, the
1448+
// content before the page break will be printed on one page and after the page
1449+
// break on another.
1450+
//
1451+
//export StreamInsertPageBreak
1452+
func StreamInsertPageBreak(swIDx int, cell *C.char) *C.char {
1453+
streamWriter, ok := sw.Load(swIDx)
1454+
if !ok {
1455+
return C.CString(errStreamWriterPtr)
1456+
}
1457+
if err := streamWriter.(*excelize.StreamWriter).InsertPageBreak(C.GoString(cell)); err != nil {
1458+
return C.CString(err.Error())
1459+
}
1460+
return C.CString(emptyString)
1461+
}
1462+
1463+
// StreamMergeCell provides a function to merge cells by a given range reference
1464+
// for the StreamWriter. Don't create a merged cell that overlaps with another
1465+
// existing merged cell.
1466+
//
1467+
//export StreamMergeCell
1468+
func StreamMergeCell(swIDx int, topLeftCell, bottomRightCell *C.char) *C.char {
1469+
streamWriter, ok := sw.Load(swIDx)
1470+
if !ok {
1471+
return C.CString(errStreamWriterPtr)
1472+
}
1473+
if err := streamWriter.(*excelize.StreamWriter).MergeCell(C.GoString(topLeftCell), C.GoString(bottomRightCell)); err != nil {
1474+
return C.CString(err.Error())
1475+
}
1476+
return C.CString(emptyString)
1477+
}
1478+
1479+
// StreamSetColWidth provides a function to set the width of a single column or
1480+
// multiple columns for the StreamWriter. Note that you must call
1481+
// the 'StreamSetColWidth' function before the 'StreamSetRow' function.
1482+
//
1483+
//export StreamSetColWidth
1484+
func StreamSetColWidth(swIDx int, minVal, maxVal int, width float64) *C.char {
1485+
streamWriter, ok := sw.Load(swIDx)
1486+
if !ok {
1487+
return C.CString(errStreamWriterPtr)
1488+
}
1489+
if err := streamWriter.(*excelize.StreamWriter).SetColWidth(minVal, maxVal, width); err != nil {
1490+
return C.CString(err.Error())
1491+
}
1492+
return C.CString(emptyString)
1493+
}
1494+
1495+
// StreamSetPanes provides a function to create and remove freeze panes and
1496+
// split panes by giving panes options for the StreamWriter. Note that you must
1497+
// call the 'StreamSetPanes' function before the 'StreamSetRow' function.
1498+
//
1499+
//export StreamSetPanes
1500+
func StreamSetPanes(swIDx int, opts *C.struct_Panes) *C.char {
1501+
var options excelize.Panes
1502+
goVal, err := cValueToGo(reflect.ValueOf(*opts), reflect.TypeOf(excelize.Panes{}))
1503+
if err != nil {
1504+
return C.CString(err.Error())
1505+
}
1506+
streamWriter, ok := sw.Load(swIDx)
1507+
if !ok {
1508+
return C.CString(errStreamWriterPtr)
1509+
}
1510+
options = goVal.Elem().Interface().(excelize.Panes)
1511+
if err := streamWriter.(*excelize.StreamWriter).SetPanes(&options); err != nil {
1512+
return C.CString(err.Error())
1513+
}
1514+
return C.CString(emptyString)
1515+
}
1516+
14461517
// StreamSetRow writes an array to stream rows by giving starting cell reference
14471518
// and a pointer to an array of values. Note that you must call the 'StreamFlush'
14481519
// function to end the streaming writing process.

test_excelize.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,30 @@ def test_stream_writer(self):
8383
self.assertEqual(str(err), "sheet SheetN does not exist")
8484
sw, err = f.new_stream_writer("Sheet1")
8585
self.assertIsNone(err)
86+
87+
self.assertIsNone(sw.insert_page_break("A1"))
88+
self.assertIsNone(sw.merge_cell("D1", "E2"))
89+
self.assertIsNone(sw.set_col_width(3, 2, 20))
90+
self.assertIsNone(
91+
sw.set_panes(
92+
excelize.Panes(
93+
freeze=True,
94+
split=False,
95+
x_split=1,
96+
y_split=0,
97+
top_left_cell="B1",
98+
active_pane="topRight",
99+
selection=[
100+
excelize.Selection(
101+
sq_ref="K16",
102+
active_cell="K16",
103+
pane="topRight",
104+
)
105+
],
106+
),
107+
)
108+
)
109+
86110
self.assertIsNone(sw.set_row("A1", ["Column1", "Column2", "Column3"]))
87111
for r in range(4, 11):
88112
row = [random.randrange(640000) for _ in range(1, 4)]
@@ -98,7 +122,7 @@ def test_stream_writer(self):
98122
),
99123
)
100124
)
101-
125+
102126
self.assertIsNone(sw.flush())
103127
self.assertIsNone(f.save_as(os.path.join("test", "TestStreamWriter.xlsx")))
104128

0 commit comments

Comments
 (0)