1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "sc.h"
#include "cmds.h"
#include "color.h"
#include "macros.h"
#include "xls.h"
#include "utils/string.h"
// xls.h is part of libxls. make sure its installed and headers are in path.
// build must be done with '-lxlsreader'
#ifdef XLS
#include <xls.h>
#endif
// this functions loads an excel file into tbl.
// As SCIM still does not handle multiple sheets,
// if the excel file has multiple sheets, only the first one is read.
// this function returns -1 in case of error
int open_xls(char * fname, char * encoding) {
#ifdef XLS
// Set date format reading LOCALE
char fmt[15] = "%d/%m/%Y";
#ifdef USELOCALE
#include <locale.h>
#include <langinfo.h>
char * loc = NULL;
char * f = NULL;
loc = setlocale(LC_TIME, "");
if (loc != NULL) {
f = nl_langinfo(D_FMT);
strcpy(fmt, f);
}
#endif
// Read XLS file
xlsWorkBook * pWB;
xlsWorkSheet * pWS;
WORD r, c;
pWB = xls_open(fname, encoding);
char line_interp[FBUFLEN] = "";
struct ent * n;
if (pWB == NULL) {
scerror("Error loading %s", fname);
return -1;
}
pWS = xls_getWorkSheet(pWB, 0); //only the first sheet
if (pWS == NULL) return -1;
xls_parseWorkSheet(pWS);
for (r = 0; r <= pWS->rows.lastrow; r++) { // rows
for (c = 0; c <= pWS->rows.lastcol; c++) { // cols
xlsCell * cell = xls_cell(pWS, r, c);
if ((! cell) || (cell->isHidden)) continue;
// TODO enable rowspan ?
//if (cell->rowspan > 1) continue;
struct st_xf_data * xf = &pWB->xfs.xf[cell->xf];
//scdebug("%d %d fmt:%d id:%x %d %d", r, c, xf->format, cell->id, cell->d, cell->l);
// these are dates
if (((xf->format >= 14 && xf->format <= 22) ||
(xf->format >= 165 && xf->format <= 180) ||
xf->format == 278 || xf->format == 185 || xf->format == 196 || xf->format
== 217 || xf->format == 326 )
&& cell->id != 0x06
//&& cell->id != 0x27e
&& cell->id != 0x0BD
&& cell->id != 0x203 ) {
sprintf(line_interp, "let %s%d=%.15g", coltoa(c), r, (cell->d - 25569) * 86400);
send_to_interp(line_interp);
n = lookat(r, c);
n->format = 0;
char * s = scxmalloc((unsigned)(strlen(fmt) + 2));
sprintf(s, "%c", 'd');
strcat(s, "%d/%m/%Y");
n->format = s;
continue;
// display the value of the cell (either numeric or string)
} else if (cell->id == 0x27e || cell->id == 0x0BD || cell->id == 0x203) {
sprintf(line_interp, "let %s%d=%.15g", coltoa(c), r, cell->d);
} else if (cell->id == 0x06) { // formula
if (cell->l == 0) { // its a number
sprintf(line_interp, "let %s%d=%.15g", coltoa(c), r, cell->d);
} else {
if (!strcmp((char *) cell->str, "bool")) { // its boolean, and test cell->d
sprintf(line_interp, "label %s%d=\"%s\"", coltoa(c), r, (int) cell->d ? "true" : "false");
} else if (! strcmp((char *) cell->str, "error")) { // formula is in error
sprintf(line_interp, "label %s%d=\"%s\"", coltoa(c), r, "error"); //FIXME
} else {
sprintf(line_interp, "label %s%d=\"%s\"", coltoa(c), r, (char *) cell->str);
}
}
} else if (cell->str != NULL) {
int pad_pos;
if ((pad_pos = str_in_str((char *) cell->str, "\n")) != -1) ((char *) cell->str)[pad_pos] = '\0'; // For spanning
// clean_carrier((char *) cell->str); // For spanning
sprintf(line_interp, "label %s%d=\"%s\"", coltoa(c), r, (char *) cell->str);
} else {
sprintf(line_interp, "label %s%d=\"%s\"", coltoa(c), r, "");
}
send_to_interp(line_interp);
}
}
xls_close_WS(pWS);
xls_close(pWB);
auto_justify(0, maxcol, DEFWIDTH);
return 0;
#else
return -1;
#endif
}
|