Skip to content

Commit e59fc8f

Browse files
committed
Feat: cell comment
1 parent 545d323 commit e59fc8f

File tree

6 files changed

+250
-49
lines changed

6 files changed

+250
-49
lines changed

include/xlswriter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,12 @@ STATIC int _compare_defined_names(lxw_defined_name *a, lxw_defined_name *b);
193193

194194
STATIC void _prepare_drawings(lxw_workbook *self);
195195
STATIC void _add_chart_cache_data(lxw_workbook *self);
196+
STATIC void _prepare_vml(lxw_workbook *self);
196197
STATIC void _prepare_defined_names(lxw_workbook *self);
197198
STATIC void _populate_range(lxw_workbook *self, lxw_series_range *range);
198199
STATIC void _populate_range_dimensions(lxw_workbook *self, lxw_series_range *range);
199200

201+
void comment_show(xls_resource_write_t *res);
200202
void zoom(xls_resource_write_t *res, zend_long zoom);
201203
void gridlines(xls_resource_write_t *res, zend_long option);
202204
void auto_filter(zend_string *range, xls_resource_write_t *res);
@@ -206,6 +208,7 @@ void freeze_panes(xls_resource_write_t *res, zend_long row, zend_long column);
206208
void set_row(zend_string *range, double height, xls_resource_write_t *res, lxw_format *format);
207209
void set_column(zend_string *range, double width, xls_resource_write_t *res, lxw_format *format);
208210
void merge_cells(zend_string *range, zval *value, xls_resource_write_t *res, lxw_format *format);
211+
void comment_writer(zend_string *comment, zend_long row, zend_long columns, xls_resource_write_t *res);
209212
void url_writer(zend_long row, zend_long columns, xls_resource_write_t *res, zend_string *url, lxw_format *format);
210213
void call_object_method(zval *object, const char *function_name, uint32_t param_count, zval *params, zval *ret_val);
211214
void chart_writer(zend_long row, zend_long columns, xls_resource_chart_t *chart_resource, xls_resource_write_t *res);

kernel/excel.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ ZEND_BEGIN_ARG_INFO_EX(xls_insert_formula_arginfo, 0, 0, 3)
152152
ZEND_ARG_INFO(0, format_handle)
153153
ZEND_END_ARG_INFO()
154154

155+
ZEND_BEGIN_ARG_INFO_EX(xls_insert_comment_arginfo, 0, 0, 3)
156+
ZEND_ARG_INFO(0, row)
157+
ZEND_ARG_INFO(0, column)
158+
ZEND_ARG_INFO(0, comment)
159+
ZEND_END_ARG_INFO()
160+
161+
ZEND_BEGIN_ARG_INFO_EX(xls_show_comment_arginfo, 0, 0, 0)
162+
ZEND_END_ARG_INFO()
163+
155164
ZEND_BEGIN_ARG_INFO_EX(xls_auto_filter_arginfo, 0, 0, 1)
156165
ZEND_ARG_INFO(0, range)
157166
ZEND_END_ARG_INFO()
@@ -705,7 +714,7 @@ PHP_METHOD(vtiful_xls, insertImage)
705714
}
706715
/* }}} */
707716

708-
/** {{{ \Vtiful\Kernel\Excel::insertImage(int $row, int $column, string $imagePath)
717+
/** {{{ \Vtiful\Kernel\Excel::insertFormula(int $row, int $column, string $formula)
709718
*/
710719
PHP_METHOD(vtiful_xls, insertFormula)
711720
{
@@ -739,6 +748,43 @@ PHP_METHOD(vtiful_xls, insertFormula)
739748
}
740749
/* }}} */
741750

751+
/** {{{ \Vtiful\Kernel\Excel::insertComment(int $row, int $column, string $comment)
752+
*/
753+
PHP_METHOD(vtiful_xls, insertComment)
754+
{
755+
zend_string *comment = NULL;
756+
zend_long row = 0, column = 0;
757+
758+
ZEND_PARSE_PARAMETERS_START(3, 3)
759+
Z_PARAM_LONG(row)
760+
Z_PARAM_LONG(column)
761+
Z_PARAM_STR(comment)
762+
ZEND_PARSE_PARAMETERS_END();
763+
764+
ZVAL_COPY(return_value, getThis());
765+
766+
xls_object *obj = Z_XLS_P(getThis());
767+
768+
WORKBOOK_NOT_INITIALIZED(obj);
769+
770+
comment_writer(comment, row, column, &obj->write_ptr);
771+
}
772+
/* }}} */
773+
774+
/** {{{ \Vtiful\Kernel\Excel::showComment()
775+
*/
776+
PHP_METHOD(vtiful_xls, showComment)
777+
{
778+
ZVAL_COPY(return_value, getThis());
779+
780+
xls_object *obj = Z_XLS_P(getThis());
781+
782+
WORKBOOK_NOT_INITIALIZED(obj);
783+
784+
comment_show(&obj->write_ptr);
785+
}
786+
/* }}} */
787+
742788
/** {{{ \Vtiful\Kernel\Excel::autoFilter(int $rowStart, int $rowEnd, int $columnStart, int $columnEnd)
743789
*/
744790
PHP_METHOD(vtiful_xls, autoFilter)
@@ -1282,6 +1328,8 @@ zend_function_entry xls_methods[] = {
12821328
PHP_ME(vtiful_xls, insertUrl, xls_insert_url_arginfo, ZEND_ACC_PUBLIC)
12831329
PHP_ME(vtiful_xls, insertImage, xls_insert_image_arginfo, ZEND_ACC_PUBLIC)
12841330
PHP_ME(vtiful_xls, insertFormula, xls_insert_formula_arginfo, ZEND_ACC_PUBLIC)
1331+
PHP_ME(vtiful_xls, insertComment, xls_insert_comment_arginfo, ZEND_ACC_PUBLIC)
1332+
PHP_ME(vtiful_xls, showComment, xls_show_comment_arginfo, ZEND_ACC_PUBLIC)
12851333
PHP_ME(vtiful_xls, mergeCells, xls_merge_cells_arginfo, ZEND_ACC_PUBLIC)
12861334
PHP_ME(vtiful_xls, setColumn, xls_set_column_arginfo, ZEND_ACC_PUBLIC)
12871335
PHP_ME(vtiful_xls, setRow, xls_set_row_arginfo, ZEND_ACC_PUBLIC)

kernel/write.c

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,24 @@ void datetime_writer(lxw_datetime *datetime, zend_long row, zend_long columns, z
208208
worksheet_write_datetime(res->worksheet, (lxw_row_t)row, (lxw_col_t)columns, datetime, value_format);
209209
}
210210

211+
/*
212+
* Write the comment to the cell
213+
*/
214+
void comment_writer(zend_string *comment, zend_long row, zend_long columns, xls_resource_write_t *res)
215+
{
216+
int error = worksheet_write_comment(res->worksheet, (lxw_row_t)row, (lxw_col_t)columns, ZSTR_VAL(comment));
217+
218+
WORKSHEET_WRITER_EXCEPTION(error);
219+
}
220+
221+
/*
222+
* Show all comments
223+
*/
224+
void comment_show(xls_resource_write_t *res)
225+
{
226+
worksheet_show_comments(res->worksheet);
227+
}
228+
211229
/*
212230
* Add the autofilter.
213231
*/
@@ -333,6 +351,9 @@ workbook_file(xls_resource_write_t *self)
333351
worksheet->active = 1;
334352
}
335353

354+
/* Prepare the worksheet VML elements such as comments. */
355+
_prepare_vml(self->workbook);
356+
336357
/* Set the defined names for the worksheets such as Print Titles. */
337358
_prepare_defined_names(self->workbook);
338359

@@ -343,7 +364,7 @@ workbook_file(xls_resource_write_t *self)
343364
_add_chart_cache_data(self->workbook);
344365

345366
/* Create a packager object to assemble sub-elements into a zip file. */
346-
packager = lxw_packager_new(self->workbook->filename, self->workbook->options.tmpdir, 0);
367+
packager = lxw_packager_new(self->workbook->filename, self->workbook->options.tmpdir, self->workbook->options.use_zip64);
347368

348369
/* If the packager fails it is generally due to a zip permission error. */
349370
if (packager == NULL) {
@@ -375,6 +396,28 @@ workbook_file(xls_resource_write_t *self)
375396
"Error = %s\n", self->workbook->filename, strerror(errno));
376397
}
377398

399+
/* If LXW_ERROR_ZIP_PARAMETER_ERROR then errno is set by zip. */
400+
if (error == LXW_ERROR_ZIP_PARAMETER_ERROR) {
401+
fprintf(stderr, "[ERROR] workbook_close(): "
402+
"Zip ZIP_PARAMERROR error while creating xlsx file '%s'. "
403+
"System error = %s\n", self->workbook->filename, strerror(errno));
404+
}
405+
406+
/* If LXW_ERROR_ZIP_BAD_ZIP_FILE then errno is set by zip. */
407+
if (error == LXW_ERROR_ZIP_BAD_ZIP_FILE) {
408+
fprintf(stderr, "[ERROR] workbook_close(): "
409+
"Zip ZIP_BADZIPFILE error while creating xlsx file '%s'. "
410+
"This may require the use_zip64 option for large files. "
411+
"System error = %s\n", self->workbook->filename, strerror(errno));
412+
}
413+
414+
/* If LXW_ERROR_ZIP_INTERNAL_ERROR then errno is set by zip. */
415+
if (error == LXW_ERROR_ZIP_INTERNAL_ERROR) {
416+
fprintf(stderr, "[ERROR] workbook_close(): "
417+
"Zip ZIP_INTERNALERROR error while creating xlsx file '%s'. "
418+
"System error = %s\n", self->workbook->filename, strerror(errno));
419+
}
420+
378421
/* The next 2 error conditions don't set errno. */
379422
if (error == LXW_ERROR_ZIP_FILE_ADD) {
380423
fprintf(stderr, "[ERROR] workbook_close(): "
@@ -398,6 +441,53 @@ void _php_vtiful_xls_close(zend_resource *rsrc TSRMLS_DC)
398441

399442
}
400443

444+
/*
445+
* Iterate through the worksheets and set up the VML objects.
446+
*/
447+
448+
STATIC void
449+
_prepare_vml(lxw_workbook *self)
450+
{
451+
lxw_worksheet *worksheet;
452+
lxw_sheet *sheet;
453+
uint32_t comment_id = 0;
454+
uint32_t vml_drawing_id = 0;
455+
uint32_t vml_data_id = 1;
456+
uint32_t vml_shape_id = 1024;
457+
uint32_t comment_count = 0;
458+
459+
STAILQ_FOREACH(sheet, self->sheets, list_pointers) {
460+
if (sheet->is_chartsheet)
461+
continue;
462+
else
463+
worksheet = sheet->u.worksheet;
464+
465+
if (!worksheet->has_vml && !worksheet->has_header_vml)
466+
continue;
467+
468+
if (worksheet->has_vml) {
469+
self->has_vml = LXW_TRUE;
470+
if (worksheet->has_comments) {
471+
self->comment_count += 1;
472+
comment_id += 1;
473+
self->has_comments = LXW_TRUE;
474+
}
475+
476+
vml_drawing_id += 1;
477+
478+
comment_count = lxw_worksheet_prepare_vml_objects(worksheet,
479+
vml_data_id,
480+
vml_shape_id,
481+
vml_drawing_id,
482+
comment_id);
483+
484+
/* Each VML should start with a shape id incremented by 1024. */
485+
vml_data_id += 1 * ((1024 + comment_count) / 1024);
486+
vml_shape_id += 1024 * ((1024 + comment_count) / 1024);
487+
}
488+
}
489+
}
490+
401491
/*
402492
* Iterate through the worksheets and store any defined names used for print
403493
* ranges or repeat rows/columns.

0 commit comments

Comments
 (0)