Added worksheet_default_row() function.

Added worksheet_default_row() function to allow setting of default
row height and hiding unused rows.

Closes #27
This commit is contained in:
John McNamara 2015-12-22 00:59:45 +00:00
parent 1ce5eafb76
commit d919935913
15 changed files with 276 additions and 13 deletions

View file

@ -34,6 +34,7 @@ my @examples = (
[ 'hide_sheet.c', 'Example of hiding a worksheet' ],
[ 'doc_properties.c', 'Example of setting workbook doc properties' ],
[ 'worksheet_protection.c', 'Example of enabling worksheet protection' ],
[ 'hide_row_col.c', 'Example of hiding worksheet rows and columns' ],
[ 'panes.c', 'Example of how to create worksheet panes' ],
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View file

@ -171,12 +171,19 @@ Next example: @ref worksheet_protection.c
@example worksheet_protection.c
Example of setting Excel worksheet protection.
Next example: @ref panes.c
Next example: @ref hide_row_col.c
@image html worksheet_protection.png
@example hide_row_col.c
Example of hiding rows and columns in an Excel worksheet.
Next example: @ref panes.c
@image html hide_row_col.png
@example panes.c
An example of how to create panes in a worksheet, both “freeze” panes and “split” panes.
An example of how to create panes in a worksheet, both "freeze" panes and "split" panes.
Back to @ref examples
@image html panes.png

40
examples/hide_row_col.c Normal file
View file

@ -0,0 +1,40 @@
/*
* An example of how to hide rows and columns using the libxlsxwriter
* library.
*
* In order to hide rows without setting each one, (of approximately 1 million
* rows), Excel uses an optimisation to hide all rows that don't have data.
*
* Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
/* Create a new workbook and add a worksheet. */
lxw_workbook *workbook = new_workbook("hide_row_col.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
lxw_row_t row;
/* Write some data. */
worksheet_write_string(worksheet, 0, 3, "Some hidden columns.", NULL);
worksheet_write_string(worksheet, 7, 0, "Some hidden rows.", NULL);
/* Hide all rows without data. */
worksheet_set_default_row(worksheet, 15, LXW_TRUE);
/* Set the height of empty rows that we do want to display even if it is */
/* the default height. */
for (row = 1; row <= 6; row++)
worksheet_set_row(worksheet, row, 15, NULL, NULL);
/* Columns can be hidden explicitly. This doesn't increase the file size. */
lxw_row_col_options options = {.hidden = 1};
worksheet_set_column(worksheet, COLS("G:XFD"), 8.43, NULL, &options);
workbook_close(workbook);
return 0;
}

View file

@ -68,7 +68,7 @@
#define LXW_DEF_COL_WIDTH 8.43
/** Default row height in Excel */
#define LXW_DEF_ROW_HEIGHT 15
#define LXW_DEF_ROW_HEIGHT 15.0
/** Error codes from worksheet functions. */
enum lxw_worksheet_error {
@ -368,6 +368,7 @@ typedef struct lxw_worksheet {
uint16_t col_formats_max;
uint8_t col_size_changed;
uint8_t row_size_changed;
uint8_t optimize;
struct lxw_row *optimize_row;
@ -409,6 +410,12 @@ typedef struct lxw_worksheet {
double margin_header;
double margin_footer;
double default_row_height;
uint32_t default_row_pixels;
uint32_t default_col_pixels;
uint8_t default_row_zeroed;
uint8_t default_row_set;
uint8_t header_footer_changed;
char header[LXW_HEADER_FOOTER_MAX];
char footer[LXW_HEADER_FOOTER_MAX];
@ -458,6 +465,7 @@ typedef struct lxw_row {
uint8_t collapsed;
uint8_t row_changed;
uint8_t data_changed;
uint8_t height_changed;
struct lxw_table_cells *cells;
/* tree management pointers for tree.h. */
@ -2301,6 +2309,37 @@ void worksheet_set_tab_color(lxw_worksheet *worksheet, lxw_color_t color);
void worksheet_protect(lxw_worksheet *worksheet, char *password,
lxw_protection *options);
/**
* @brief Set the default row properties.
*
* @param worksheet Pointer to a lxw_worksheet instance to be updated.
* @param height Default row height.
* @param hide_unused_rows Hide unused cells.
*
* The `%worksheet_set_default_row()` function is used to set Excel default
* row properties such as the default height and the option to hide unused
* rows. These parameters are an optimization used by Excel to set row
* properties without generating a very large file with an entry for each row.
*
* To set the default row height:
*
* @code
* worksheet_set_default_row(worksheet, 24, LXW_FALSE);
*
* @endcode
*
* To hide unused rows:
*
* @code
* worksheet_set_default_row(worksheet, 15, LXW_TRUE);
* @endcode
*
* Note, in the previous case we use the default height #LXW_DEF_ROW_HEIGHT =
* 15 so the the height remains unchanged.
*/
void worksheet_set_default_row(lxw_worksheet *worksheet, double height,
uint8_t hide_unused_rows);
lxw_worksheet *_new_worksheet(lxw_worksheet_init_data *init_data);
void _free_worksheet(lxw_worksheet *worksheet);
void _worksheet_assemble_xml_file(lxw_worksheet *worksheet);

View file

@ -99,6 +99,10 @@ _new_worksheet(lxw_worksheet_init_data *init_data)
worksheet->dim_rowmin = LXW_ROW_MAX;
worksheet->dim_colmin = LXW_COL_MAX;
worksheet->default_row_height = LXW_DEF_ROW_HEIGHT;
worksheet->default_row_pixels = 20;
worksheet->default_col_pixels = 64;
/* Initialize the page setup properties. */
worksheet->fit_height = 0;
worksheet->fit_width = 0;
@ -1186,10 +1190,15 @@ _worksheet_write_sheet_format_pr(lxw_worksheet *self)
{
struct xml_attribute_list attributes;
struct xml_attribute *attribute;
char default_row_height[] = "15";
_INIT_ATTRIBUTES();
_PUSH_ATTRIBUTES_STR("defaultRowHeight", default_row_height);
_PUSH_ATTRIBUTES_DBL("defaultRowHeight", self->default_row_height);
if (self->default_row_height != LXW_DEF_ROW_HEIGHT)
_PUSH_ATTRIBUTES_STR("customHeight", "1");
if (self->default_row_zeroed)
_PUSH_ATTRIBUTES_STR("zeroHeight", "1");
_xml_empty_tag(self->file, "sheetFormatPr", &attributes);
@ -1394,11 +1403,17 @@ _write_row(lxw_worksheet *self, lxw_row *row, char *spans)
struct xml_attribute_list attributes;
struct xml_attribute *attribute;
int32_t xf_index = 0;
double height;
if (row->format) {
xf_index = _get_xf_index(row->format);
}
if (row->height_changed)
height = row->height;
else
height = self->default_row_height;
_INIT_ATTRIBUTES();
_PUSH_ATTRIBUTES_INT("r", row->row_num + 1);
@ -1411,13 +1426,13 @@ _write_row(lxw_worksheet *self, lxw_row *row, char *spans)
if (row->format)
_PUSH_ATTRIBUTES_STR("customFormat", "1");
if (row->height != LXW_DEF_ROW_HEIGHT)
_PUSH_ATTRIBUTES_INT("ht", row->height);
if (height != LXW_DEF_ROW_HEIGHT)
_PUSH_ATTRIBUTES_INT("ht", height);
if (row->hidden)
_PUSH_ATTRIBUTES_STR("hidden", "1");
if (row->height != LXW_DEF_ROW_HEIGHT)
if (height != LXW_DEF_ROW_HEIGHT)
_PUSH_ATTRIBUTES_STR("customHeight", "1");
if (row->collapsed)
@ -1641,7 +1656,12 @@ _worksheet_write_rows(lxw_worksheet *self)
RB_FOREACH(row, lxw_table_rows, self->table) {
if (RB_EMPTY(row->cells)) {
/* Row data only. No cells. */
/* Row contains no cells but has height, format or other data. */
/* Write a default span for default rows. */
if (self->default_row_set)
_write_row(self, row, "1:1");
else
_write_row(self, row, NULL);
}
else {
@ -3024,8 +3044,7 @@ worksheet_set_row(lxw_worksheet *self,
/* If the height is 0 the row is hidden and the height is the default. */
if (height == 0) {
hidden = LXW_TRUE;
height = LXW_DEF_ROW_HEIGHT;
height = self->default_row_height;
}
row = _get_row(self, row_num);
@ -3037,8 +3056,10 @@ worksheet_set_row(lxw_worksheet *self,
row->collapsed = collapsed;
row->row_changed = LXW_TRUE;
return 0;
if (height != self->default_row_height)
row->height_changed = LXW_TRUE;
return 0;
}
/*
@ -3725,3 +3746,24 @@ worksheet_protect(lxw_worksheet *self, char *password,
protect->is_configured = LXW_TRUE;
}
/*
* Set the default row properties
*/
void
worksheet_set_default_row(lxw_worksheet *self, double height,
uint8_t hide_unused_rows)
{
if (height < 0)
height = self->default_row_height;
if (height != self->default_row_height) {
self->default_row_height = height;
self->row_size_changed = LXW_TRUE;
}
if (hide_unused_rows)
self->default_row_zeroed = LXW_TRUE;
self->default_row_set = LXW_TRUE;
}

View file

@ -0,0 +1,23 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = new_workbook("test_default_row01.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
worksheet_set_default_row(worksheet, 24, LXW_FALSE);
worksheet_write_string(worksheet, CELL("A1"), "Foo" , NULL);
worksheet_write_string(worksheet, CELL("A10"), "Bar" , NULL);
return workbook_close(workbook);
}

View file

@ -0,0 +1,27 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = new_workbook("test_default_row02.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
uint8_t row;
worksheet_set_default_row(worksheet, 15, LXW_TRUE);
worksheet_write_string(worksheet, CELL("A1"), "Foo" , NULL);
worksheet_write_string(worksheet, CELL("A10"), "Bar" , NULL);
for (row = 1; row <= 8; row++)
worksheet_set_row(worksheet, row, 15, NULL, NULL);
return workbook_close(workbook);
}

View file

@ -0,0 +1,27 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = new_workbook("test_default_row03.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
uint8_t row;
worksheet_set_default_row(worksheet, 24, LXW_TRUE);
worksheet_write_string(worksheet, CELL("A1"), "Foo" , NULL);
worksheet_write_string(worksheet, CELL("A10"), "Bar" , NULL);
for (row = 1; row <= 8; row++)
worksheet_set_row(worksheet, row, 24, NULL, NULL);
return workbook_close(workbook);
}

View file

@ -0,0 +1,31 @@
/*****************************************************************************
* Test cases for libxlsxwriter.
*
* Test to compare output against Excel files.
*
* Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
*
*/
#include "xlsxwriter.h"
int main() {
lxw_workbook *workbook = new_workbook("test_default_row05.xlsx");
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
uint8_t row;
worksheet_set_default_row(worksheet, 24, LXW_TRUE);
worksheet_write_string(worksheet, CELL("A1"), "Foo" , NULL);
worksheet_write_string(worksheet, CELL("A10"), "Bar" , NULL);
worksheet_write_string(worksheet, CELL("A20"), "Baz" , NULL);
for (row = 1; row <= 8; row++)
worksheet_set_row(worksheet, row, 24, NULL, NULL);
for (row = 10; row <= 19; row++)
worksheet_set_row(worksheet, row, 24, NULL, NULL);
return workbook_close(workbook);
}

View file

@ -0,0 +1,26 @@
###############################################################################
#
# Tests for libxlsxwriter.
#
# Copyright 2014-2015, John McNamara, jmcnamara@cpan.org
#
import base_test_class
class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
"""
Test file created with libxlsxwriter against a file created by Excel.
"""
def test_default_row01(self):
self.run_exe_test('test_default_row01')
def test_default_row02(self):
self.run_exe_test('test_default_row02')
def test_default_row03(self):
self.run_exe_test('test_default_row03')
def test_default_row05(self):
self.run_exe_test('test_default_row05')

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.