mirror of
https://github.com/jmcnamara/libxlsxwriter
synced 2025-03-28 21:13:14 +00:00
Added external workbook hyperlinks.
This commit is contained in:
parent
a160ef0ddc
commit
da1e35edab
115
src/worksheet.c
115
src/worksheet.c
@ -137,8 +137,8 @@ _free_cell(lxw_cell *cell)
|
||||
if (!cell)
|
||||
return;
|
||||
|
||||
if (cell->type == FORMULA_CELL || cell->type == ARRAY_FORMULA_CELL
|
||||
|| cell->type == INLINE_STRING_CELL || cell->type == HYPERLINK_URL) {
|
||||
if (cell->type != NUMBER_CELL && cell->type != STRING_CELL
|
||||
&& cell->type != BLANK_CELL) {
|
||||
|
||||
free(cell->u.string);
|
||||
}
|
||||
@ -1663,8 +1663,8 @@ _worksheet_write_auto_filter(lxw_worksheet *self)
|
||||
*/
|
||||
STATIC void
|
||||
_worksheet_write_hyperlink_external(lxw_worksheet *self, lxw_row_t row_num,
|
||||
lxw_col_t col_num, const char *tooltip,
|
||||
uint16_t id)
|
||||
lxw_col_t col_num, const char *location,
|
||||
const char *tooltip, uint16_t id)
|
||||
{
|
||||
struct xml_attribute_list attributes;
|
||||
struct xml_attribute *attribute;
|
||||
@ -1679,6 +1679,9 @@ _worksheet_write_hyperlink_external(lxw_worksheet *self, lxw_row_t row_num,
|
||||
_PUSH_ATTRIBUTES_STR("ref", ref);
|
||||
_PUSH_ATTRIBUTES_STR("r:id", r_id);
|
||||
|
||||
if (location)
|
||||
_PUSH_ATTRIBUTES_STR("location", location);
|
||||
|
||||
if (tooltip)
|
||||
_PUSH_ATTRIBUTES_STR("tooltip", tooltip);
|
||||
|
||||
@ -1740,7 +1743,8 @@ _worksheet_write_hyperlinks(lxw_worksheet *self)
|
||||
|
||||
TAILQ_FOREACH(link, row->cells, list_pointers) {
|
||||
|
||||
if (link->type == HYPERLINK_URL) {
|
||||
if (link->type == HYPERLINK_URL
|
||||
|| link->type == HYPERLINK_EXTERNAL) {
|
||||
|
||||
self->rel_count++;
|
||||
|
||||
@ -1761,6 +1765,7 @@ _worksheet_write_hyperlinks(lxw_worksheet *self)
|
||||
|
||||
_worksheet_write_hyperlink_external(self, link->row_num,
|
||||
link->col_num,
|
||||
link->user_data1,
|
||||
link->user_data2,
|
||||
self->rel_count);
|
||||
}
|
||||
@ -2151,9 +2156,14 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
||||
lxw_cell *link;
|
||||
char *url_copy = NULL;
|
||||
char *string_copy = NULL;
|
||||
char *url_string = NULL;
|
||||
char *url_external = NULL;
|
||||
char *tooltip_copy = NULL;
|
||||
char *tmp_str;
|
||||
char *found_string;
|
||||
int8_t err;
|
||||
size_t string_size;
|
||||
size_t i;
|
||||
|
||||
enum cell_types link_type = HYPERLINK_URL;
|
||||
|
||||
if (!url || !strlen(url))
|
||||
@ -2163,28 +2173,35 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
tmp_str = strstr(url, "internal:");
|
||||
|
||||
if (tmp_str)
|
||||
/* Set the URI scheme from internal links. */
|
||||
found_string = strstr(url, "internal:");
|
||||
if (found_string)
|
||||
link_type = HYPERLINK_INTERNAL;
|
||||
|
||||
/* Set the URI scheme from external links. */
|
||||
found_string = strstr(url, "external:");
|
||||
if (found_string)
|
||||
link_type = HYPERLINK_EXTERNAL;
|
||||
|
||||
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
|
||||
if (link_type == HYPERLINK_URL) {
|
||||
/* Strip the mailto header. */
|
||||
found_string = strstr(url, "mailto:");
|
||||
if (found_string)
|
||||
string_copy = lxw_strdup(url + sizeof("mailto"));
|
||||
else
|
||||
string_copy = lxw_strdup(url);
|
||||
}
|
||||
else {
|
||||
string_copy = lxw_strdup(url + sizeof("__ternal"));
|
||||
|
||||
}
|
||||
GOTO_LABEL_ON_MEM_ERROR(string_copy, mem_error);
|
||||
}
|
||||
|
||||
err = worksheet_write_string(self, row_num, col_num, string_copy, format);
|
||||
if (err)
|
||||
goto mem_error;
|
||||
|
||||
if (url) {
|
||||
if (link_type == HYPERLINK_URL)
|
||||
url_copy = lxw_strdup(url);
|
||||
@ -2199,8 +2216,68 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
||||
GOTO_LABEL_ON_MEM_ERROR(tooltip_copy, mem_error);
|
||||
}
|
||||
|
||||
if (link_type == HYPERLINK_INTERNAL) {
|
||||
url_string = lxw_strdup(string_copy);
|
||||
GOTO_LABEL_ON_MEM_ERROR(url_string, mem_error);
|
||||
}
|
||||
|
||||
if (link_type == HYPERLINK_EXTERNAL) {
|
||||
/* External Workbook links need to be modified into the right format.
|
||||
* The URL will look something like "c:\temp\file.xlsx#Sheet!A1".
|
||||
* We need the part to the left of the # as the URL and the part to
|
||||
* the right as the "location" string (if it exists).
|
||||
*/
|
||||
|
||||
/* For external links change the dir separator from Unix to DOS. */
|
||||
for (i = 0; i <= strlen(url_copy); i++)
|
||||
if (url_copy[i] == '/')
|
||||
url_copy[i] = '\\';
|
||||
|
||||
for (i = 0; i <= strlen(string_copy); i++)
|
||||
if (string_copy[i] == '/')
|
||||
string_copy[i] = '\\';
|
||||
|
||||
found_string = strchr(url_copy, '#');
|
||||
|
||||
if (found_string) {
|
||||
url_string = lxw_strdup(found_string + 1);
|
||||
GOTO_LABEL_ON_MEM_ERROR(url_string, mem_error);
|
||||
|
||||
*found_string = '\0';
|
||||
}
|
||||
|
||||
/* Look for Windows style "C:/" link or Windows share "\\" link. */
|
||||
found_string = strchr(url_copy, ':');
|
||||
if (!found_string)
|
||||
found_string = strstr(url_copy, "\\\\");
|
||||
|
||||
if (found_string) {
|
||||
/* Add the file:/// URI to the url if non-local. */
|
||||
string_size = sizeof("file:///") + strlen(url_copy);
|
||||
url_external = calloc(1, string_size);
|
||||
GOTO_LABEL_ON_MEM_ERROR(url_external, mem_error);
|
||||
|
||||
__builtin_snprintf(url_external, string_size, "file:///%s",
|
||||
url_copy);
|
||||
|
||||
}
|
||||
|
||||
if (url_external) {
|
||||
free(url_copy);
|
||||
url_copy = lxw_strdup(url_external);
|
||||
GOTO_LABEL_ON_MEM_ERROR(url_copy, mem_error);
|
||||
|
||||
free(url_external);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = worksheet_write_string(self, row_num, col_num, string_copy, format);
|
||||
if (err)
|
||||
goto mem_error;
|
||||
|
||||
link = _new_hyperlink_cell(row_num, col_num, link_type, url_copy,
|
||||
string_copy, tooltip_copy);
|
||||
url_string, tooltip_copy);
|
||||
GOTO_LABEL_ON_MEM_ERROR(link, mem_error);
|
||||
|
||||
_insert_hyperlink(self, row_num, col_num, link);
|
||||
@ -2210,6 +2287,8 @@ worksheet_write_url_opt(lxw_worksheet *self,
|
||||
mem_error:
|
||||
free(string_copy);
|
||||
free(url_copy);
|
||||
free(url_external);
|
||||
free(url_string);
|
||||
free(tooltip_copy);
|
||||
return -5;
|
||||
}
|
||||
|
22
test/functional/src/test_hyperlink06.c
Normal file
22
test/functional/src/test_hyperlink06.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink06.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_url_opt(worksheet, CELL("A1"), "external:C:\\Temp\\foo.xlsx", NULL, NULL, NULL);
|
||||
worksheet_write_url_opt(worksheet, CELL("A3"), "external:C:\\Temp\\foo.xlsx#Sheet1!A1", NULL, NULL, NULL);
|
||||
worksheet_write_url_opt(worksheet, CELL("A5"), "external:C:\\Temp\\foo.xlsx#Sheet1!A1", NULL, "External", "Tip");
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
21
test/functional/src/test_hyperlink07.c
Normal file
21
test/functional/src/test_hyperlink07.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink07.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_url_opt(worksheet, CELL("A1"), "external:\\\\VBOXSVR\\share\\foo.xlsx", NULL, "J:\\foo.xlsx", NULL);
|
||||
worksheet_write_url( worksheet, CELL("A3"), "external:foo.xlsx" , NULL);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
22
test/functional/src/test_hyperlink08.c
Normal file
22
test/functional/src/test_hyperlink08.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink08.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
/* Test with forward slashes instead of back slashes in test_hyperlink07.c. */
|
||||
worksheet_write_url_opt(worksheet, CELL("A1"), "external://VBOXSVR/share/foo.xlsx", NULL, "J:/foo.xlsx", NULL);
|
||||
worksheet_write_url( worksheet, CELL("A3"), "external:foo.xlsx" , NULL);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
22
test/functional/src/test_hyperlink09.c
Normal file
22
test/functional/src/test_hyperlink09.c
Normal file
@ -0,0 +1,22 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink09.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
|
||||
worksheet_write_url(worksheet, CELL("A1"), "external:..\\foo.xlsx" , NULL);
|
||||
worksheet_write_url(worksheet, CELL("A3"), "external:..\\foo.xlsx#Sheet1!A1" , NULL);
|
||||
worksheet_write_url_opt(worksheet, CELL("A5"), "external:\\\\VBOXSVR\\share\\foo.xlsx#Sheet1!B2", NULL, "J:\\foo.xlsx#Sheet1!B2", NULL);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
24
test/functional/src/test_hyperlink10.c
Normal file
24
test/functional/src/test_hyperlink10.c
Normal file
@ -0,0 +1,24 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink10.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
|
||||
format_set_underline(format, LXW_UNDERLINE_SINGLE);
|
||||
format_set_font_color(format, LXW_COLOR_RED);
|
||||
|
||||
worksheet_write_url(worksheet, CELL("A1"), "http://www.perl.org/", format);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
24
test/functional/src/test_hyperlink11.c
Normal file
24
test/functional/src/test_hyperlink11.c
Normal file
@ -0,0 +1,24 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink11.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
|
||||
format_set_underline(format, LXW_UNDERLINE_SINGLE);
|
||||
format_set_font_color(format, LXW_COLOR_BLUE);
|
||||
|
||||
worksheet_write_url(worksheet, CELL("A1"), "http://www.perl.org/", format);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
25
test/functional/src/test_hyperlink12.c
Normal file
25
test/functional/src/test_hyperlink12.c
Normal file
@ -0,0 +1,25 @@
|
||||
/*****************************************************************************
|
||||
* 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_hyperlink12.xlsx");
|
||||
lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL);
|
||||
lxw_format *format = workbook_add_format(workbook);
|
||||
|
||||
format_set_underline(format, LXW_UNDERLINE_SINGLE);
|
||||
format_set_font_color(format, LXW_COLOR_BLUE);
|
||||
|
||||
worksheet_write_url(worksheet, CELL("A1"), "mailto:jmcnamara@cpan.org", format);
|
||||
worksheet_write_url(worksheet, CELL("A3"), "ftp://perl.org/", format);
|
||||
|
||||
return workbook_close(workbook);
|
||||
}
|
@ -28,4 +28,24 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest):
|
||||
def test_hyperlink05(self):
|
||||
self.run_exe_test('test_hyperlink05')
|
||||
|
||||
|
||||
def test_hyperlink06(self):
|
||||
self.run_exe_test('test_hyperlink06')
|
||||
|
||||
def test_hyperlink07(self):
|
||||
self.run_exe_test('test_hyperlink07')
|
||||
|
||||
def test_hyperlink08(self):
|
||||
self.run_exe_test('test_hyperlink08')
|
||||
|
||||
def test_hyperlink09(self):
|
||||
self.run_exe_test('test_hyperlink09')
|
||||
|
||||
def test_hyperlink10(self):
|
||||
self.run_exe_test('test_hyperlink10')
|
||||
|
||||
def test_hyperlink11(self):
|
||||
self.run_exe_test('test_hyperlink11')
|
||||
|
||||
def test_hyperlink12(self):
|
||||
self.run_exe_test('test_hyperlink12')
|
||||
|
||||
|
BIN
test/functional/xlsx_files/hyperlink06.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink06.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink07.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink07.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink08.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink08.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink09.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink09.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink10.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink10.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink11.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink11.xlsx
Normal file
Binary file not shown.
BIN
test/functional/xlsx_files/hyperlink12.xlsx
Normal file
BIN
test/functional/xlsx_files/hyperlink12.xlsx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user