1 ## Copyright (C) 2009,2010,2011,2012 Philip Nienhuis <prnienhuis at users.sf.net>
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
17 ## @deftypefn {Function File} [@var{filetype}] = odsfinfo (@var{filename} [, @var{reqintf}])
18 ## @deftypefnx {Function File} [@var{filetype}, @var{sh_names}] = odsfinfo (@var{filename} [, @var{reqintf}])
19 ## Query an OpenOffice_org spreadsheet file @var{filename} (with ods
20 ## suffix) for some info about its contents.
22 ## If @var{filename} is a recognizable OpenOffice.org spreadsheet file,
23 ## @var{filetype} returns the string "OpenOffice.org Calc spreadsheet",
24 ## or @'' (empty string) otherwise.
26 ## If @var{filename} is a recognizable OpenOffice.org Calc spreadsheet
27 ## file, optional argument @var{sh_names} contains a list (cell array)
28 ## of sheet names contained in @var{filename}, in the order (from left
29 ## to right) in which they occur in the sheet stack.
31 ## If you omit return arguments @var{filetype} and @var{sh_names} altogether,
32 ## odsfinfo returns the sheet names and for each sheet the actual occupied
33 ## data ranges to the screen.The occupied cell range will have to be
34 ## determined behind the scenes first; this can take some time.
36 ## odsfinfo execution can take its time for large spreadsheets as the entire
37 ## spreadsheet has to be parsed to get the sheet names, let alone exploring
40 ## By specifying a value of 'jod', 'otk' or 'uno' for @var{reqintf} the automatic
41 ## selection of the java interface is bypassed and the specified interface
42 ## will be used (if at all present).
47 ## exist = odsfinfo ('test4.ods');
48 ## (Just checks if file test4.ods is a readable Calc file)
52 ## [exist, names] = odsfinfo ('test4.ods');
53 ## (Checks if file test4.ods is a readable Calc file and return a
54 ## list of sheet names)
57 ## @seealso {odsread, odsopen, ods2oct, odsclose}
61 ## Author: Philip Nienhuis <pr.nienhuis at users.sf.net>
62 ## Created: 2009-12-17
64 ## 2010-01-03 Added functionality for JOD as well
65 ## 2010-03-03 Fixed echo of proper number of occupied data rows
66 ## 2010-03-18 Fixed proper echo of occupied data range
67 ## (ah those pesky table-row-repeated & table-column-repeated attr.... :-( )
68 ## 2010-03-18 Separated range exploration (for OTK only yet) in separate function file
69 ## 2010-03-20 "Beautified" output (for OTK ), used range now in more tabular form
70 ## 2010-05-23 Updated jOpenDocument support (can also get occupied data range now)
71 ## 2010-05-31 Added remark about delays when determining occupied data range
72 ## 2011-03-23 Adapted to odfdom 0.8.7 (changed getXPath method call)
73 ## 2011-05-07 Experimental UNO support added
74 ## 2011-09-03 Normal return in case of no ODS support (empty ods struct)
75 ## 2012-01-26 Fixed "seealso" help string
76 ## 2012-02-25 Return occupied sheet ranges in output args
77 ## '' Improve echo of sheet names & ranges if interactive
78 ## 2012-03-01 Fix wrong cell refs in UNO section ("(..)" rather than "{..}"
79 ## 2012-06-08 Support for odfdom-0.8.8-incubator
81 function [ filetype, sheetnames ] = odsfinfo (filename, reqintf=[])
83 onscreen = nargout < 1;
85 ods = odsopen (filename, 0, reqintf);
86 # If no ods support was found, odsopen will have complained. Just return here
87 if (isempty (ods)), return; endif
89 filetype = 'OpenOffice.org Calc Document';
91 persistent adj_str; adj_str = ' '; # 30 char filler string
93 # To save execution time, only proceed if sheet names are wanted
96 if (strcmp (ods.xtype, 'OTK'))
97 # Get contents and table (= sheet) stuff from the workbook
98 odfcont = ods.workbook; # Local copy just in case
99 if (strcmp (ods.odfvsn, '0.8.7') || strfind (ods.odfvsn, "0.8.8"))
100 xpath = ods.workbook.getXPath;
102 xpath = ods.app.getXPath;
105 # Create an instance of type NODESET for use in subsequent statement
106 NODESET = java_get ('javax.xml.xpath.XPathConstants', 'NODESET');
107 # Parse sheets ("tables") from ODS file
108 sheets = xpath.evaluate ("//table:table", odfcont, NODESET);
109 nr_of_sheets = sheets.getLength();
110 sheetnames = cell (nr_of_sheets, 2);
112 # Get sheet names (& optionally date row count estimate)
113 for ii=1:nr_of_sheets
114 # Check in first part of the sheet nodeset
115 sheetnames (ii) = sheets.item(ii-1).getTableNameAttribute ();
116 [ tr, lr, lc, rc ] = getusedrange (ods, ii);
118 printf (sprintf("%s", sheetnames{ii}));
120 printf (sprintf("%s (used range = %s:%s)", \
121 adj_str(1:(30 - length (sheetnames{ii}))), \
122 calccelladdress (tr, lc), calccelladdress (lr, rc)));
124 printf ("%s (empty)", adj_str(1:(30 - length (sheetnames{ii}))));
129 sheetnames(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc));
133 elseif (strcmp (ods.xtype, 'JOD'))
134 nr_of_sheets = ods.workbook.getSheetCount ();
135 sheetnames = cell (nr_of_sheets, 2);
136 for ii=1:nr_of_sheets
137 sheetnames(ii) = ods.workbook.getSheet (ii-1).getName ();
138 [ tr, lr, lc, rc ] = getusedrange (ods, ii);
140 printf (sprintf("%s", sheetnames{ii}));
142 printf (sprintf("%s (used range = %s:%s)", \
143 adj_str(1:(30 - length (sheetnames{ii}))), \
144 calccelladdress (tr, lc), calccelladdress (lr, rc)));
146 printf ("%s (empty)", adj_str(1:(30 - length (sheetnames{ii}))));
151 sheetnames(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc));
155 elseif (strcmp (ods.xtype, 'UNO'))
156 sheets = ods.workbook.getSheets ();
157 sheetnames = sheets.getElementNames (); # A Java object, NOT a cell array
158 nr_of_sheets = numel (sheetnames);
159 sheetnames = char (sheetnames);
160 for ii=1:nr_of_sheets
161 [ tr, lr, lc, rc ] = getusedrange (ods, ii);
163 printf (sprintf("%s", sheetnames{ii})); # () as it is a Java object
165 printf (sprintf ("%s (used range = %s:%s)", \
166 adj_str (1:(30 - length (sheetnames{ii}))), \
167 calccelladdress (tr, lc), calccelladdress (lr, rc)));
169 printf ("%s (empty)", adj_str(1:(30 - length (sheetnames{ii}))));
174 sheetnames(ii, 2) = sprintf ("%s:%s", calccelladdress (tr, lc), calccelladdress (lr, rc));
180 # error (sprintf ("odsfinfo: unknown OpenOffice.org .ods interface - %s.", ods.xtype));
185 ods = odsclose (ods);