-
Notifications
You must be signed in to change notification settings - Fork 0
/
loadods.m
156 lines (137 loc) · 3.92 KB
/
loadods.m
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
% LOADODS: Loads data from an open document spreadsheet (ods) file into a cell
% array
%
% SYNTAX: data = loadods(filename,options)
%
% INPUTS:
% filename: String representing the path and name of the ods file
% options: Structural variable containing optional arguments
%
% OUTPUTS:
% data: MxN cell array containing data from the spreadsheet
%
% OPTIONS:
% sheet_name: Name of a specific sheet to load [defaults to the first sheet]
% blank: Value to store for blank spreadsheet cells [NaN]
%
% VERSION: 1.0
%
% Copyright (C) 2007 Alex Marten - [email protected]
function data = loadods(filename,options)
% Set default options
if nargin<2, options = []; end
if ~isfield(options,'sheet_name'), options.sheet_name = []; end
if ~isfield(options,'blank'), options.blank = nan; end
% Check for the existence of the ods file
if exist(filename)~=2
error('The file does not exist');
end
% Create a temporary directory to unzip the ods file into
if ~mkdir(tempdir,filename)
error('Permission error');
end
dir_temp = strcat(tempdir,filename);
% Unzip the contents of the ods file
unzip(filename,dir_temp);
% Load the XML file containing the spreadsheet data
try
XMLfile = xmlread(strcat(dir_temp,'/content.xml'));
catch
error('Unable to read the spreadsheet data');
end
% Parse down to the <office:spreadsheet> node
nodes = XMLfile.getChildNodes;
node = nodes.item(0);
nodes = node.getChildNodes;
node = nodes.item(3);
nodes = node.getChildNodes;
node = nodes.item(0);
nodes = node.getChildNodes;
% Find the requested sheet by name or default to the first sheet
if ~isempty(options.sheet_name)
numSheets = nodes.getLength;
for count = 1:numSheets
sheet = nodes.item(count-1);
if strcmp(get_attribute(sheet,'table:name'),options.sheet_name)
break
end
end
else
sheet = nodes.item(0);
end
% Get the number of columns
nodes = sheet.getChildNodes;
num_nodes = nodes.getLength;
num_cols = 0;
for count = 1:num_nodes
node = nodes.item(count-1);
if strcmp(char(node.getNodeName),'table:table-column')
temp = get_attribute(node,'table:number-columns-repeated');
if ~isempty(temp)
num_cols = num_cols+str2num(char(num_cols));
end
elseif strcmp(char(node.getNodeName),'table:table-row')
count = count-2;
break
end
end
% Get the number of rows
num_rows = num_nodes-count-1;
% Initialize memory for the data
data = cell(num_rows,num_cols);
% Extract the data for the sheet
for row_num = 1:num_rows
row = nodes.item(count+row_num);
cols = row.getChildNodes;
col_num = 0;
num_items = cols.getLength-1;
for item_num = 0:num_items
col = cols.item(item_num);
num_repeated = get_attribute(col,'table:number-columns-repeated');
num_repeated = str2num(char(num_repeated));
value_type = get_attribute(col,'office:value-type');
if strcmp(value_type,'string')
temp = col.getChildNodes;
temp = temp.item(0);
temp = temp.getChildNodes;
temp = temp.item(0);
if any(strcmp(methods(temp),'getData'))
value = char(temp.getData);
else
value = options.blank;
end
elseif strcmp(value_type,'float')
value = str2num(get_attribute(col,'office:value'));
else
value = options.blank;
end
if ~isempty(num_repeated)
for i = 1:num_repeated
col_num = col_num+1;
data{row_num,col_num} = value;
end
else
col_num = col_num+1;
data{row_num,col_num} = value;
end
end
end
% Remove the temporary files
if ~rmdir(dir_temp,'s')
warning('Temporary files could not be removed');
end
end
% Returns the value of the attribute_name in node
function attribute = get_attribute(node,attribute_name)
attribute = [];
if node.hasAttributes
attributes = node.getAttributes;
num_attributes = attributes.getLength;
for count = 1:num_attributes
item = attributes.item(count-1);
if strcmp(char(item.getName),attribute_name)
attribute = char(item.getValue);
end
end
end
end