mirror of
https://github.com/jmcnamara/libxlsxwriter.git
synced 2026-05-21 06:45:21 -06:00
Added internal hyperlinks.
This commit is contained in:
parent
9dae8f2c2e
commit
a160ef0ddc
5 changed files with 119 additions and 27 deletions
|
|
@ -111,7 +111,9 @@ enum cell_types {
|
|||
FORMULA_CELL,
|
||||
ARRAY_FORMULA_CELL,
|
||||
BLANK_CELL,
|
||||
HYPERLLINK_URL
|
||||
HYPERLINK_URL,
|
||||
HYPERLINK_INTERNAL,
|
||||
HYPERLINK_EXTERNAL
|
||||
};
|
||||
|
||||
/* Define the queue.h TAILQ structs for the list head types. */
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ _free_cell(lxw_cell *cell)
|
|||
return;
|
||||
|
||||
if (cell->type == FORMULA_CELL || cell->type == ARRAY_FORMULA_CELL
|
||||
|| cell->type == INLINE_STRING_CELL || cell->type == HYPERLLINK_URL) {
|
||||
|| cell->type == INLINE_STRING_CELL || cell->type == HYPERLINK_URL) {
|
||||
|
||||
free(cell->u.string);
|
||||
}
|
||||
|
|
@ -391,15 +391,16 @@ _new_blank_cell(lxw_row_t row_num, lxw_col_t col_num, lxw_format *format)
|
|||
* Create a new worksheet hyperlink cell object.
|
||||
*/
|
||||
STATIC lxw_cell *
|
||||
_new_hyperlink_cell(lxw_row_t row_num, lxw_col_t col_num, char *url,
|
||||
char *string, char *tooltip)
|
||||
_new_hyperlink_cell(lxw_row_t row_num, lxw_col_t col_num,
|
||||
enum cell_types link_type, char *url, char *string,
|
||||
char *tooltip)
|
||||
{
|
||||
lxw_cell *cell = calloc(1, sizeof(lxw_cell));
|
||||
RETURN_ON_MEM_ERROR(cell, cell);
|
||||
|
||||
cell->row_num = row_num;
|
||||
cell->col_num = col_num;
|
||||
cell->type = HYPERLLINK_URL;
|
||||
cell->type = link_type;
|
||||
cell->u.string = url;
|
||||
cell->user_data1 = string;
|
||||
cell->user_data2 = tooltip;
|
||||
|
|
@ -1658,7 +1659,7 @@ _worksheet_write_auto_filter(lxw_worksheet *self)
|
|||
}
|
||||
|
||||
/*
|
||||
* Write the <hyperlink> element.
|
||||
* Write the <hyperlink> element for external links.
|
||||
*/
|
||||
STATIC void
|
||||
_worksheet_write_hyperlink_external(lxw_worksheet *self, lxw_row_t row_num,
|
||||
|
|
@ -1686,6 +1687,37 @@ _worksheet_write_hyperlink_external(lxw_worksheet *self, lxw_row_t row_num,
|
|||
_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the <hyperlink> element for internal links.
|
||||
*/
|
||||
STATIC void
|
||||
_worksheet_write_hyperlink_internal(lxw_worksheet *self, lxw_row_t row_num,
|
||||
lxw_col_t col_num, const char *location,
|
||||
const char *display, const char *tooltip)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
char ref[MAX_CELL_NAME_LENGTH];
|
||||
|
||||
lxw_rowcol_to_cell(ref, row_num, col_num);
|
||||
|
||||
_INIT_ATTRIBUTES();
|
||||
_PUSH_ATTRIBUTES_STR("ref", ref);
|
||||
|
||||
if (location)
|
||||
_PUSH_ATTRIBUTES_STR("location", location);
|
||||
|
||||
if (tooltip)
|
||||
_PUSH_ATTRIBUTES_STR("tooltip", tooltip);
|
||||
|
||||
if (display)
|
||||
_PUSH_ATTRIBUTES_STR("display", display);
|
||||
|
||||
_xml_empty_tag(self->file, "hyperlink", &attributes);
|
||||
|
||||
_FREE_ATTRIBUTES();
|
||||
}
|
||||
|
||||
/*
|
||||
* Process any stored hyperlinks in row/col order and write the <hyperlinks>
|
||||
* element. The attributes are different for internal and external links.
|
||||
|
|
@ -1708,6 +1740,8 @@ _worksheet_write_hyperlinks(lxw_worksheet *self)
|
|||
|
||||
TAILQ_FOREACH(link, row->cells, list_pointers) {
|
||||
|
||||
if (link->type == HYPERLINK_URL) {
|
||||
|
||||
self->rel_count++;
|
||||
|
||||
relationship = calloc(1, sizeof(lxw_rel_tuple));
|
||||
|
|
@ -1731,6 +1765,17 @@ _worksheet_write_hyperlinks(lxw_worksheet *self)
|
|||
self->rel_count);
|
||||
}
|
||||
|
||||
if (link->type == HYPERLINK_INTERNAL) {
|
||||
|
||||
_worksheet_write_hyperlink_internal(self, link->row_num,
|
||||
link->col_num,
|
||||
link->u.string,
|
||||
link->user_data1,
|
||||
link->user_data2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_xml_end_tag(self->file, "hyperlinks");
|
||||
|
|
@ -2107,8 +2152,9 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
|||
char *url_copy = NULL;
|
||||
char *string_copy = NULL;
|
||||
char *tooltip_copy = NULL;
|
||||
char *tmp_str;
|
||||
int8_t err;
|
||||
/*uint8_t link_type = 1; */
|
||||
enum cell_types link_type = HYPERLINK_URL;
|
||||
|
||||
if (!url || !strlen(url))
|
||||
return -4;
|
||||
|
|
@ -2117,12 +2163,21 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
tmp_str = strstr(url, "internal:");
|
||||
|
||||
if (tmp_str)
|
||||
link_type = HYPERLINK_INTERNAL;
|
||||
|
||||
if (string) {
|
||||
string_copy = lxw_strdup(string);
|
||||
GOTO_LABEL_ON_MEM_ERROR(string_copy, mem_error);
|
||||
}
|
||||
else {
|
||||
if (link_type == HYPERLINK_URL)
|
||||
string_copy = lxw_strdup(url);
|
||||
else
|
||||
string_copy = lxw_strdup(url + sizeof("__ternal"));
|
||||
|
||||
GOTO_LABEL_ON_MEM_ERROR(string_copy, mem_error);
|
||||
}
|
||||
|
||||
|
|
@ -2131,7 +2186,11 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
|||
goto mem_error;
|
||||
|
||||
if (url) {
|
||||
if (link_type == HYPERLINK_URL)
|
||||
url_copy = lxw_strdup(url);
|
||||
else
|
||||
url_copy = lxw_strdup(url + sizeof("__ternal"));
|
||||
|
||||
GOTO_LABEL_ON_MEM_ERROR(url_copy, mem_error);
|
||||
}
|
||||
|
||||
|
|
@ -2140,7 +2199,7 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
|||
GOTO_LABEL_ON_MEM_ERROR(tooltip_copy, mem_error);
|
||||
}
|
||||
|
||||
link = _new_hyperlink_cell(row_num, col_num, url_copy,
|
||||
link = _new_hyperlink_cell(row_num, col_num, link_type, url_copy,
|
||||
string_copy, tooltip_copy);
|
||||
GOTO_LABEL_ON_MEM_ERROR(link, mem_error);
|
||||
|
||||
|
|
|
|||
31
test/functional/src/test_hyperlink04.c
Normal file
31
test/functional/src/test_hyperlink04.c
Normal 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_hyperlink04.xlsx");
|
||||
lxw_worksheet *worksheet1 = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_worksheet *worksheet2 = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_worksheet *worksheet3 = workbook_add_worksheet(workbook, "Data Sheet");
|
||||
|
||||
(void)worksheet2;
|
||||
(void)worksheet3;
|
||||
|
||||
worksheet_write_url_opt(worksheet1, CELL("A1"), "internal:Sheet2!A1", NULL, NULL, NULL);
|
||||
worksheet_write_url_opt(worksheet1, CELL("A3"), "internal:Sheet2!A1:A5", NULL, NULL, NULL);
|
||||
worksheet_write_url_opt(worksheet1, CELL("A5"), "internal:'Data Sheet'!D5", NULL, "Some text", NULL);
|
||||
worksheet_write_url_opt(worksheet1, CELL("E12"), "internal:Sheet1!J1", NULL, NULL, NULL);
|
||||
worksheet_write_url_opt(worksheet1, CELL("G17"), "internal:Sheet2!A1", NULL, "Some text", NULL);
|
||||
worksheet_write_url_opt(worksheet1, CELL("A18"), "internal:Sheet2!A1", NULL, NULL, "Tool Tip 1");
|
||||
worksheet_write_url_opt(worksheet1, CELL("A20"), "internal:Sheet2!A1", NULL, "More text", "Tool Tip 2");
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
||||
|
|
@ -22,8 +22,8 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
|
|||
def test_hyperlink03(self):
|
||||
self.run_exe_test('test_hyperlink03')
|
||||
|
||||
# def test_hyperlink04(self):
|
||||
# self.run_exe_test('test_hyperlink04')
|
||||
def test_hyperlink04(self):
|
||||
self.run_exe_test('test_hyperlink04')
|
||||
|
||||
def test_hyperlink05(self):
|
||||
self.run_exe_test('test_hyperlink05')
|
||||
|
|
|
|||
BIN
test/functional/xlsx_files/hyperlink04.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink04.xlsx
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue