Added external workbook hyperlinks.

This commit is contained in:
John McNamara 2015-05-03 03:33:20 +01:00
parent a160ef0ddc
commit da1e35edab
16 changed files with 278 additions and 19 deletions

View File

@ -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;
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View 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);
}

View File

@ -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')

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.