From: <prn...@us...> - 2009-12-30 15:51:05
|
Revision: 6682 http://octave.svn.sourceforge.net/octave/?rev=6682&view=rev Author: prnienhuis Date: 2009-12-30 15:50:56 +0000 (Wed, 30 Dec 2009) Log Message: ----------- Folded the individual scripts for each interface into the wrapper functions (e.g. xls2com2oct.m now is in the xls2oct.m script file) to needless directory clutter. Updated help text in scripts. Moved check on file extensions in xlsopen to the individual interface sections, as Excel can read more than just xls. Cleaned up code here and there. Modified Paths: -------------- trunk/octave-forge/main/io/inst/oct2xls.m trunk/octave-forge/main/io/inst/xls2oct.m trunk/octave-forge/main/io/inst/xlsfinfo.m trunk/octave-forge/main/io/inst/xlsopen.m trunk/octave-forge/main/io/inst/xlsread.m Modified: trunk/octave-forge/main/io/inst/oct2xls.m =================================================================== --- trunk/octave-forge/main/io/inst/oct2xls.m 2009-12-30 15:10:35 UTC (rev 6681) +++ trunk/octave-forge/main/io/inst/oct2xls.m 2009-12-30 15:50:56 UTC (rev 6682) @@ -25,10 +25,6 @@ ## Return argument @var{xlso} equals supplied argument @var{xlsi} and is ## updated by oct2xls. ## -## oct2xls is a mere wrapper for interface-dependent scripts (e.g., -## oct2com2xls, oct2jpoi2xls, oct2jxla2xls) that do the actual writing to -## spreadsheet files. -## ## A subsequent call to xlsclose is needed to write the updated spreadsheet ## to disk (and -if needed- close the Excel or Java invocation). ## @@ -75,7 +71,7 @@ ## Author: Philip Nienhuis ## Created: 2009-12-01 -## Latest update: 2009-12-11 +## Latest update: 2009-12-30 function [ xls, rstatus ] = oct2xls (obj, xls, wsh, topleft='A1') @@ -100,6 +96,539 @@ # elseif (strcmp'xls.xtype, '<whatever>')) # <Other Excel interfaces> + else + error (sprintf ("oct2xls: unknown Excel .xls interface - %s.", xls.xtype)); + endif endfunction + + +#=================================================================================== +## Copyright (C) 2007 by Michael Goffioul <michael.goffioul at swing.be> +## +## Adapted by P.R. Nienhuis <prnienhuis at users.sf.net> (2009) +## for more flexible writing into Excel worksheets through COM. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; If not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [@var{xlso}, @var{status}] = oct2com2xls (@var{obj}, @var{xlsi}) +## @deftypefnx {Function File} [@var{xlso}, @var{status}] = oct2com2xls (@var{obj}, @var{xlsi}, @var{wsh}) +## @deftypefnx {Function File} [@var{xlso}, @var{status}] = oct2com2xls (@var{obj}, @var{xlsi}, @var{wsh}, @var{top_left_cell}) +## Save matrix @var{obj} into worksheet @var{wsh} in Excel file pointed +## to in struct @var{xlsi}. All elements of @var{obj} are converted into +## Excel cells, starting at cell @var{top_left_cell}. Return argument +## @var{xlso} is @var{xlsi} with updated fields. +## +## oct2com2xls should not be invoked directly but rather through oct2xls. +## +## Excel invocations may be left running invisibly in case of COM errors. +## +## Example: +## +## @example +## xls = oct2com2xls (rand (10, 15), xls, 'Third_sheet', 'BF24'); +## @end example +## +## @seealso oct2xls, xls2oct, xlsopen, xlsclose, xlswrite, xlsread, xls2com2oct +## +## @end deftypefn + +## Author: Philip Nienhuis +## Rewritten: 2009-09-26 +## Last updated 2009-12-11 + +function [ xls, status ] = oct2com2xls (obj, xls, wsh, top_left_cell='A1') + + # define some constants not yet in __COM__.cc + xlWorksheet = -4167; # xlChart= 4; + + # scratch vars + status = 0; + + # Preliminary sanity checks + if (nargin < 2) error ("oct2com2xls needs a minimum of 2 arguments."); endif + if (nargin == 2) wsh = 1; endif + if (~iscell (obj)) error ("Cell array expected as input argument"); endif + if (~strcmp (tolower (xls.filename(end-3:end)), '.xls')) + error ("oct2com2xls can only write to Excel .xls files") + endif + if (isnumeric (wsh)) + if (wsh < 1) error ("Illegal worksheet number: %i\n", wsh); endif + elseif (size (wsh, 2) > 31) + error ("Illegal worksheet name - too long") + endif + if (isempty (obj)) + warning ("Request to write empty matrix."); + rstatus = 1; + return; + endif + test1 = ~isfield (xls, "xtype"); + test1 = test1 || ~isfield (xls, "workbook"); + test1 = test1 || ~strcmp (char (xls.xtype), 'COM'); + test1 = test1 || isempty (xls.workbook); + test1 = test1 || isempty (xls.app); + if test1 + error ("Invalid file pointer struct"); + endif + + # Cleanup NaNs. Start with backing up strings, empty & boolean cells, + # then set text cells to 0 + obj2 = cell (size (obj)); + txtptr = cellfun ('isclass', obj, 'char'); + if (any(txtptr)) obj2{txtptr} = obj{txtptr}; obj{txtptr} = 0; endif + eptr = cellfun ('isempty', obj); + if (any (eptr)) obj{eptr} = 0; endif + lptr = cellfun ("islogical" , obj); + if (any (lptr)) obj2{lptr} = obj{lptr}; obj{lptr} = 0; endif + + ptr = cellfun ("isnan", obj); + if (any (ptr)) obj{ptr} = []; endif + + # Restore text & booleans + if (any (txtptr)) obj{txtptr} = obj2{txtptr}; endif + if (any (lptr)) obj{lptr} = obj2{lptr}; endif + clear obj2 txtptr eptr lptr ptr; + + if (xls.changed < 2) + # Existing file. Some involved investigation is needed to preserve + # existing data that shouldn't be touched. + # + # See if desired *sheet* name exists. + old_sh = 0; + ws_cnt = xls.workbook.Sheets.count; + if (isnumeric (wsh)) + if (wsh <= ws_cnt) + # Here we check for sheet *position* in the sheet stack + # rather than a name like "Sheet<Number>" + old_sh = wsh; + else + # wsh > nr of sheets; proposed new sheet name. + # This sheet name can already exist to the left in the sheet stack! + shnm = sprintf ("Sheet%d", wsh); shnm1 = shnm; + endif + endif + if (~old_sh) + # Check if the requested (or proposed) sheet already exists + # COM objects are not OO (yet?), so we need a WHILE loop + ii = 1; jj = 1; + while ((ii <= ws_cnt) && ~old_sh) + # Get existing sheet names one by one + sh_name = xls.workbook.Sheets(ii).name; + if (~isnumeric (wsh) && strcmp (sh_name, wsh)) + # ...and check with requested sheet *name*... + old_sh = ii; + elseif (isnumeric (wsh) && strcmp (sh_name, shnm)) + # ... or proposed new sheet name (corresp. to requested sheet *number*) + shnm = [shnm "_"]; + ii = 0; # Also check if this new augmented sheet name exists... + if (strmatch (shnm1, sh_name)), jj++; endif + if (jj > 5) # ... but not unlimited times... + error (sprintf (" > 5 sheets named [_]Sheet%d already present!", wsh)); + endif + endif + ++ii; + endwhile + endif + + if (old_sh) + # Requested sheet exists. Check if it is a *work*sheet + if ~(xls.workbook.Sheets(old_sh).Type == xlWorksheet) + # Error as you can't write data to this + error (sprintf ("Existing sheet '%s' is not type worksheet.", wsh)); + else + # Simply point to the relevant sheet + sh = xls.workbook.Worksheets (old_sh); + endif + else + # Add a new worksheet. Earlier it was checked whether this is safe + sh = xls.workbook.Worksheets.Add (); + if (~isnumeric (wsh)) + sh.Name = wsh; + else + sh.Name = shnm; + printf ("Writing to worksheet %s\n", shnm); + endif + # Prepare to move new sheet to right of the worksheet stack anyway + ws_cnt = xls.workbook.Worksheets.count; # New count needed + # Find where Excel has left it. We have to, depends on Excel version :-( + ii = 1; + while ((ii < ws_cnt+1) && ~strcmp (sh.Name, xls.workbook.Worksheets(ii).Name) == 1) + ++ii; + endwhile + # Excel can't move it beyond the current last one, so we need a trick. + # First move it to just before the last one.... + xls.workbook.Worksheets(ii).Move (before = xls.workbook.Worksheets(ws_cnt)); + # ....then move the last one before the new sheet. + xls.workbook.Worksheets (ws_cnt).Move (before = xls.workbook.Worksheets(ws_cnt - 1)); + endif + xls.changed = 1; + + else + # The easy case: a new Excel file. + # Workbook was created in xlsopen. Write to first worksheet: + sh = xls.workbook.Worksheets (1); + # Delete empty non-used sheets, last one first + xls.app.Application.DisplayAlerts = 0; + xls.workbook.Worksheets(3).Delete(); xls.workbook.Worksheets(2).Delete(); + xls.app.Application.DisplayAlerts = 1; + + # Rename the sheet + if (isnumeric(wsh)) + sh.Name = sprintf("Sheet%i", wsh); + else + sh.Name = wsh; + endif + xls.changed = 2; + endif + + # MG's original part. + # Save object in Excel sheet, starting at cell top_left_cell + if (~isempty(obj)) + r = sh.Range (top_left_cell); + r = r.Resize (size (obj, 1), size (obj, 2)); + r.Value = obj; + delete (r); + endif + + # If we get here, all went OK + status = 1; + +endfunction + + +#==================================================================================== +## Copyright (C) 2009 Philip Nienhuis <prnienhuis at users.sf.net> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jpoi2xls ( @var{arr}, @var{xlsi}) +## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jpoi2xls (@var{arr}, @var{xlsi}, @var{wsh}) +## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jpoi2xls (@var{arr}, @var{xlsi}, @var{wsh}, @var{topleft}) +## +## Add data in 1D/2D CELL array @var{arr} into a range with upper left +## cell equal to @var{topleft} in worksheet @var{wsh} in an Excel +## spreadsheet file pointed to in structure @var{range}. +## Return argument @var{xlso} equals supplied argument @var{xlsi} and is +## updated by oct2java2xls. +## +## oct2jpoi2xls should not be invoked directly but rather through oct2xls. +## +## Example: +## +## @example +## [xlso, status] = xls2jpoi2oct ('arr', xlsi, 'Third_sheet', 'AA31'); +## @end example +## +## @seealso oct2xls, xls2oct, xlsopen, xlsclose, xlsread, xlswrite +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-11-26 +## Last updated 2009-12-11 + +function [ xls, rstatus ] = oct2jpoi2xls (obj, xls, wsh, topleftcell="A1") + + persistent ctype; + if (isempty (ctype)) + # Get cell types. Beware as they start at 0 not 1 + ctype(1) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_NUMERIC'); + ctype(2) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_STRING'); + ctype(3) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_FORMULA'); + ctype(4) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BLANK'); + ctype(5) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BOOLEAN'); + ctype(6) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_ERROR'); + endif + + # scratch vars + rstatus = 0; changed = 1; + + # Preliminary sanity checks + if (isempty (obj)) + warning ("Request to write empty matrix."); + rstatus = 1; + return; + elseif (~iscell(obj)) + error ("First argument is not a cell array"); + endif + if (nargin < 2) error ("oct2jpoi2xls needs a minimum of 2 arguments."); endif + if (nargin == 2) wsh = 1; endif + if (~strmatch(tolower(xls.filename(end-4:end)), '.xls')) + error ("oct2jpoi2xls can only write to Excel .xls or .xlsx files") + endif + # Check if xls struct pointer seems valid + test1 = ~isfield (xls, "xtype"); + test1 = test1 || ~isfield (xls, "workbook"); + test1 = test1 || ~strcmp (char (xls.xtype), 'POI'); + test1 = test1 || isempty (xls.workbook); + test1 = test1 || isempty (xls.app); + if test1 error ("Invalid xls file struct"); endif + + # Check if requested worksheet exists in the file & if so, get pointer + nr_of_sheets = xls.workbook.getNumberOfSheets(); + if (isnumeric (wsh)) + if (wsh > nr_of_sheets) + # Watch out as a sheet called Sheet%d can exist with a lower index... + strng = sprintf ("Sheet%d", wsh); + ii = 1; + while (~isempty (xls.workbook.getSheet (strng)) && (ii < 5)) + strng = ['_' strng]; + ++ii; + endwhile + if (ii >= 5) error (sprintf( " > 5 sheets named [_]Sheet%d already present!", wsh)); endif + sh = xls.workbook.createSheet (strng); + else + sh = xls.workbook.getSheetAt (wsh - 1); # POI sheet count 0-based + endif + printf ("(Writing to worksheet %s)\n", sh.getSheetName()); + else + sh = xls.workbook.getSheet (wsh); + if (isempty(sh)) + # Sheet not found, just create it + sh = xls.workbook.createSheet (wsh); + xls.changed = 2; + endif + endif + + # Beware of strings variables interpreted as char arrays; change them to cell. + if (ischar (obj)) obj = {obj}; endif + + [topleft, nrows, ncols, trow, lcol] = parse_sp_range (topleftcell); + [nrows, ncols] = size (obj); + + # Prepare type array + typearr = ctype(4) * ones (nrows, ncols); # type "BLANK", provisionally + obj2 = cell (size (obj)); # Temporary storage for strings + + txtptr = cellfun ('isclass', obj, 'char'); # type "STRING" replaced by "NUMERIC" + obj2(txtptr) = obj(txtptr); obj(txtptr) = ctype(1); # Save strings in a safe place + + emptr = cellfun ("isempty", obj); + obj(emptr) = ctype(1); # Set empty cells to NUMERIC + + lptr = cellfun ("islogical" , obj); # Find logicals... + obj2(lptr) = obj(lptr); # .. and set them to BOOLEAN + + ptr = cellfun ("isnan", obj); # Find NaNs & set to BLANK + typearr(ptr) = ctype(4); typearr(~ptr) = ctype(1); # All other cells are now numeric + + obj(txtptr) = obj2(txtptr); # Copy strings back into place + obj(lptr) = obj2(lptr); + typearr(txtptr) = ctype(2); # ...and clean up + typearr(emptr) = ctype(4); + typearr(lptr) = ctype(5); # BOOLEAN + + # Create formula evaluator (needed to be able to write boolean values!) + frm_eval = xls.workbook.getCreationHelper().createFormulaEvaluator(); + + for ii=1:nrows + ll = ii + trow - 2; # Java POI's row count = 0-based + row = sh.getRow (ll); + if (isempty (row)) row = sh.createRow (ll); endif + for jj=1:ncols + kk = jj + lcol - 2; # POI's column count is also 0-based + cell = row.createCell (kk, typearr(ii,jj)); + if (typearr(ii, jj) == ctype(5)) + cell = row.createCell (kk, ctype(3)); + # Provisionally we make do with formulas evaluated immediately 8-Z + if obj{ii, jj} bool = '(1=1)'; else bool = '(1=0)'; endif + cell.setCellFormula (bool); frm_eval.evaluateInCell (cell); + elseif ~(typearr(ii, jj) == 3) + # Just put text or number in cell + cell.setCellValue (obj{ii, jj}); + endif + endfor + endfor + + rstatus = 1; + +endfunction + + +#==================================================================================== +## Copyright (C) 2009 Philip Nienhuis <prnienhuis at users.sf.net> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jxla2xls ( @var{arr}, @var{xlsi}) +## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jxla2xls (@var{arr}, @var{xlsi}, @var{wsh}) +## @deftypefnx {Function File} [ @var{xlso}, @var{rstatus} ] = oct2jxla2xls (@var{arr}, @var{xlsi}, @var{wsh}, @var{topleft}) +## +## Add data in 1D/2D CELL array @var{arr} into a range with upper left +## cell equal to @var{topleft} in worksheet @var{wsh} in an Excel +## spreadsheet file pointed to in structure @var{range}. +## Return argument @var{xlso} equals supplied argument @var{xlsi} and is +## updated by oct2jxla2xls. +## +## oct2jxla2xls should not be invoked directly but rather through oct2xls. +## +## Example: +## +## @example +## [xlso, status] = oct2jxla2oct ('arr', xlsi, 'Third_sheet', 'AA31'); +## @end example +## +## @seealso oct2xls, xls2oct, xlsopen, xlsclose, xlsread, xlswrite, xls2jxla2oct +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-12-04 +## Last updated 2009-12-11 + +function [ xls, rstatus ] = oct2jxla2xls (obj, xls, wsh, topleftcell="A1") + + persistent ctype; + if (isempty (ctype)) + ctype = [1, 2, 3, 4, 5]; + # Boolean, Number, String, NaN, Empty + endif + + # scratch vars + rstatus = 0; changed = 1; + + # Preliminary sanity checks + if (isempty (obj)) + warning ("Request to write empty matrix."); + rstatus = 1; + return; + elseif (~iscell(obj)) + error ("First argument is not a cell array"); + endif + if (nargin < 2) error ("oct2java2xls needs a minimum of 2 arguments."); endif + if (nargin == 2) wsh = 1; endif + if (~strmatch(tolower(xls.filename(end-4:end)), '.xls')) # FIXME for OOXML + error ("oct2java2xls can only write to Excel .xls files") + endif + + # Prepare workbook pointer if needed + if (xls.changed < 2) + # Create writable copy of workbook. If 2 a writable wb was made in xlsopen + xlsout = java_new ('java.io.File', xls.filename); + wb = java_invoke ('jxl.Workbook', 'createWorkbook', xlsout, xls.workbook); + xls.changed = 1; # For in case we come from reading the file + xls.workbook = wb; + else + wb = xls.workbook; + endif + + # Check if requested worksheet exists in the file & if so, get pointer + nr_of_sheets = xls.workbook.getNumberOfSheets(); # 1 based !! + if (isnumeric (wsh)) + if (wsh > nr_of_sheets) + # Watch out as a sheet called Sheet%d can exist with a lower index... + strng = sprintf ("Sheet%d", wsh); + ii = 1; + while (~isempty (wb.getSheet (strng)) && (ii < 5)) + strng = ['_' strng]; + ++ii; + endwhile + if (ii >= 5) error (sprintf( " > 5 sheets named [_]Sheet%d already present!", wsh)); endif + sh = wb.createSheet (strng, nr_of_sheets); ++nr_of_sheets; + else + sh = wb.getSheet (wsh - 1); # POI sheet count 0-based + endif + shnames = char(wb.getSheetNames ()); + printf ("(Writing to worksheet %s)\n", shnames {nr_of_sheets, 1}); + else + sh = wb.getSheet (wsh); + if (isempty(sh)) + # Sheet not found, just create it + sh = wb.createSheet (wsh, nr_of_sheets); + ++nr_of_sheets; + xls.changed = 2; + endif + endif + + # Beware of strings variables interpreted as char arrays; change them to cell. + if (ischar (obj)) obj = {obj}; endif + + [topleft, nrows, ncols, trow, lcol] = parse_sp_range (topleftcell); + [nrows, ncols] = size (obj); + + # Prepare type array to speed up writing + typearr = 5 * ones (nrows, ncols); # type "EMPTY", provisionally + obj2 = cell (size (obj)); # Temporary storage for strings + + txtptr = cellfun ('isclass', obj, 'char'); # type "STRING" replaced by "NUMERIC" + obj2(txtptr) = obj(txtptr); obj(txtptr) = 3; # Save strings in a safe place + + emptr = cellfun ("isempty", obj); + obj(emptr) = 5; # Set empty cells to NUMERIC + + lptr = cellfun ("islogical" , obj); # Find logicals... + obj2(lptr) = obj(lptr); # .. and set them to BOOLEAN + + ptr = cellfun ("isnan", obj); # Find NaNs & set to BLANK + typearr(ptr) = 4; typearr(~ptr) = 2; # All other cells are now numeric + + obj(txtptr) = obj2(txtptr); # Copy strings back into place + obj(lptr) = obj2(lptr); + typearr(txtptr) = 3; # ...and clean up + typearr(emptr) = 5; + typearr(lptr) = 1; # BOOLEAN + + # Write date to worksheet + for ii=1:nrows + ll = ii + trow - 2; # Java JExcelAPI's row count = 0-based + for jj=1:ncols + kk = jj + lcol - 2; # JExcelAPI's column count is also 0-based + switch typearr(ii, jj) + case 1 # Boolean + tmp = java_new ('jxl.write.Boolean', kk, ll, obj{ii, jj}); + sh.addCell (tmp); + case 2 # Numerical + tmp = java_new ('jxl.write.Number', kk, ll, obj{ii, jj}); + sh.addCell (tmp); + case 3 # String + tmp = java_new ('jxl.write.Label', kk, ll, obj{ii, jj}); + sh.addCell (tmp); + otherwise + # Just skip + endswitch + endfor + endfor + + rstatus = 1; + +endfunction + Modified: trunk/octave-forge/main/io/inst/xls2oct.m =================================================================== --- trunk/octave-forge/main/io/inst/xls2oct.m 2009-12-30 15:10:35 UTC (rev 6681) +++ trunk/octave-forge/main/io/inst/xls2oct.m 2009-12-30 15:50:56 UTC (rev 6682) @@ -22,10 +22,6 @@ ## Read data contained within range @var{range} from worksheet @var{wsh} ## in an Excel spreadsheet file pointed to in struct @var{xls}. ## -## xls2oct is a mere wrapper for interface-dependent scripts (e.g., -## xls2com2oct, xls2jpoi2oct and xls2jxla2oct) that do the actual -## reading. -## ## @var{wsh} is either numerical or text, in the latter case it is ## case-sensitive and it may be max. 31 characters long. ## Note that in case of a numerical @var{wsh} this number refers to the @@ -91,7 +87,7 @@ ## Author: Philip Nienhuis ## Created: 2009-10-16 -## Latest update: 2009-12-11 +## Latest update: 2009-12-30 function [ rawarr, xls, rstatus ] = xls2oct (xls, wsh, datrange='') @@ -102,9 +98,512 @@ # Read xls file tru Java POI [rawarr, xls, rstatus] = xls2jpoi2oct (xls, wsh, datrange); elseif (strcmp (xls.xtype, 'JXL')) + # Read xls file tru JExcelAPI [rawarr, xls, rstatus] = xls2jxla2oct (xls, wsh, datrange); # elseif ---- <Other interfaces here> + + else + error (sprintf ("xls2oct: unknown Excel .xls interface - %s.", xls.xtype)); + endif endfunction + + +#==================================================================================== +## Copyright (C)2009 P.R. Nienhuis, <pr.nienhuis at hccnet.nl> +## +## based on mat2xls by Michael Goffioul (2007) <mic...@sw...> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; If not, see <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2com2oct (@var{xls}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2com2oct (@var{xls}, @var{wsh}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2com2oct (@var{xls}, @var{wsh}, @var{range}) +## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel +## file pointed to in struct @var{xls} into the cell array @var{obj}. +## +## xls2com2oct should not be invoked directly but rather through xls2oct. +## +## Examples: +## +## @example +## [Arr, status, xls] = xls2com2oct (xls, 'Second_sheet', 'B3:AY41'); +## Arr = xls2com2oct (xls, 'Second_sheet'); +## @end example +## +## @seealso xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-09-23 +## Last updated 2009-12-11 + +function [obj, xls, rstatus ] = xls2com2oct (xls, wsh, range) + + rstatus = 0; obj = {}; + + # Basic checks + if (nargin < 2) error ("xls2com2oct needs a minimum of 2 arguments."); endif + if (size (wsh, 2) > 31) + warning ("Worksheet name too long - truncated") + wsh = wsh(1:31); + endif + + nrows = 0; + emptyrange = 0; + if ((nargin == 2) || (isempty (range))) + emptyrange = 1; + else + # Extract top_left_cell from range + [topleft, nrows, ncols] = parse_sp_range (range); + endif; + + if (nrows >= 1 || emptyrange) + # Check the file handle struct + test1 = ~isfield (xls, "xtype"); + test1 = test1 || ~isfield (xls, "workbook"); + test1 = test1 || ~strcmp (char (xls.xtype), 'COM'); + test1 = test1 || isempty (xls.workbook); + test1 = test1 || isempty (xls.app); + if test1 + error ("Invalid file pointer struct"); + endif + app = xls.app; + wb = xls.workbook; + wb_cnt = wb.Worksheets.count; + old_sh = 0; + if (isnumeric (wsh)) + if (wsh < 1 || wsh > wb_cnt) + errstr = sprintf ("Worksheet number: %d out of range 1-%d", wsh, wb_cnt); + error (errstr) + return + else + old_sh = wsh; + endif + else + # Find worksheet number corresponding to name in wsh + wb_cnt = wb.Worksheets.count; + for ii =1:wb_cnt + sh_name = wb.Worksheets(ii).name; + if (strcmp (sh_name, wsh)) old_sh = ii; endif + endfor + if (~old_sh) + errstr = sprintf ("Worksheet name \"%s\" not present", wsh); + error (errstr) + else + wsh = old_sh; + endif + endif + + sh = wb.Worksheets (wsh); + + if (emptyrange) + allcells = sh.UsedRange; + obj = allcells.Value; + else + # Get object from Excel sheet, starting at cell top_left_cell + r = sh.Range (topleft); + r = r.Resize (nrows, ncols); + obj = r.Value; + delete (r); + endif; + # Take care of actual singe cell range + if (isnumeric (obj) || ischar (obj)) + obj = {obj}; + endif + # If we get here, all seems to have gone OK + rstatus = 1; + + else + error ("No data read from Excel file"); + rstatus = 0; + + endif + +endfunction + + +#================================================================================== +## Copyright (C) 2009 Philip Nienhuis <prnienhuis at users.sf.net> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jpoi2oct (@var{xls}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jpoi2oct (@var{xls}, @var{wsh}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jpoi2oct (@var{xls}, @var{wsh}, @var{range}) +## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel +## file pointed to in struct @var{xls} into the cell array @var{obj}. +## @var{range} can be a range or just the top left cell of the range. +## +## xls2jpoi2oct should not be invoked directly but rather through xls2oct. +## +## Examples: +## +## @example +## [Arr, status, xls] = xls2jpoi2oct (xls, 'Second_sheet', 'B3:AY41'); +## B = xls2jpoi2oct (xls, 'Second_sheet', 'B3'); +## @end example +## +## @seealso xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite, oct2jpoi2xls +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-11-23 +## Last updated 2009-12-11 + +function [ rawarr, xls, status ] = xls2jpoi2oct (xls, wsh, cellrange=[]) + + persistent ctype; + if (isempty (ctype)) + # Get enumrated cell types. Beware as they start at 0 not 1 + ctype(1) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_NUMERIC'); + ctype(2) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_STRING'); + ctype(3) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_FORMULA'); + ctype(4) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BLANK'); + ctype(5) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_BOOLEAN'); + ctype(6) = java_get ('org.apache.poi.ss.usermodel.Cell', 'CELL_TYPE_ERROR'); + endif + + status = 0; jerror = 0; + + # Check if xls struct pointer seems valid + test1 = ~isfield (xls, "xtype"); + test1 = test1 || ~isfield (xls, "workbook"); + test1 = test1 || ~strcmp (char (xls.xtype), 'POI'); + test1 = test1 || isempty (xls.workbook); + test1 = test1 || isempty (xls.app); + if test1 + error ("Invalid xls file struct"); + else + wb = xls.workbook; + endif + + # Check if requested worksheet exists in the file & if so, get pointer + nr_of_sheets = wb.getNumberOfSheets (); + if (isnumeric (wsh)) + if (wsh > nr_of_sheets), error (sprintf ("Worksheet # %d bigger than nr. of sheets (%d) in file %s", wsh, nr_of_sheets, xls.filename)); endif + sh = wb.getSheetAt (wsh - 1); # POI sheet count 0-based + printf ("(Reading from worksheet %s)\n", sh.getSheetName ()); + else + sh = wb.getSheet (wsh); + if (isempty (sh)), error (sprintf("Worksheet %s not found in file %s", wsh, xls.filename)); endif + end + + # Check ranges + firstrow = sh.getFirstRowNum (); + lastrow = sh.getLastRowNum (); + if (isempty (cellrange)) + # Get used range by searching (slow...). Beware, it can be bit unreliable + lcol = 65535; # FIXME for OOXML + rcol = 0; + for ii=firstrow:lastrow + irow = sh.getRow (ii); + if (~isempty (irow)) + scol = (irow.getFirstCellNum).intValue (); + lcol = min (lcol, scol); + ecol = (irow.getLastCellNum).intValue () - 1; + rcol = max (rcol, ecol); + # Keep track of lowermost non-empty row as getLastRowNum() is unreliable + if ~(irow.getCell(scol).getCellType () == ctype(4) && irow.getCell(ecol).getCellType () == ctype(4)) + botrow = ii; + endif + endif + endfor + lastrow = min (lastrow, botrow); + nrows = lastrow - firstrow + 1; + ncols = rcol - lcol + 1; + else + # Translate range to HSSF POI row & column numbers + [topleft, nrows, ncols, trow, lcol] = parse_sp_range (cellrange); + firstrow = max (trow-1, firstrow); + lastrow = firstrow + nrows - 1; + lcol = lcol -1; # POI rows & column # 0-based + endif + + # Create formula evaluator (needed to infer proper cell type into rawarr) + # NB formula evaluation is not very reliable in POI + frm_eval = wb.getCreationHelper().createFormulaEvaluator (); + + #wb.clearAllCachedResultsValues(); # does not work + + # Read contents into rawarr + rawarr = cell (nrows, ncols); # create placeholder + for ii = firstrow:lastrow + irow = sh.getRow (ii); + if ~isempty (irow) + scol = (irow.getFirstCellNum).intValue (); + ecol = (irow.getLastCellNum).intValue () - 1; + for jj = max (scol, lcol) : min (lcol+ncols-1, ecol) + cell = irow.getCell (jj); + if ~isempty (cell) + # Process cell contents + type_of_cell = cell.getCellType (); + if (type_of_cell == ctype(3)) # Formula + try + cell = frm_eval.evaluate (cell); + type_of_cell = cell.getCellType(); + switch type_of_cell + case ctype (1) # Numeric + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getNumberValue (); + case ctype(2) # String + rawarr (ii+1-firstrow, jj+1-lcol) = char (cell.getStringValue ()); + case ctype (5) # Boolean + rawarr (ii+1-firstrow, jj+1-lcol) = cell.BooleanValue (); + otherwise + # Nothing to do here + endswitch + catch + # In case of errors we copy the formula as text into rawarr + rawarr (ii+1-firstrow, jj+1-lcol) = ["=" cell.getCellFormula]; + type_of_cell = ctype (4); + if (~jerror) + warning ("Java errors in worksheet formulas (converted to string)"); + endif + ++jerror; # We only need one warning + end_try_catch + else + if (~isnumeric (type_of_cell)) type_of_cell = 4; endif + switch type_of_cell + case ctype(1) # 0 Numeric + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getNumericCellValue (); + case ctype(2) # 1 String + rawarr (ii+1-firstrow, jj+1-lcol) = char (cell.getRichStringCellValue ()); +# case ctype(3) # 2 Formula (if still at all needed). +# try # Provisionally we simply take the result +# rawarr (ii+1-firstrow, jj+1-lcol) = cell.getNumericCellValue (); +# catch +# # In case of errors we copy the formula as text into rawarr +# rawarr (ii+1-firstrow, jj+1-lcol) = ["=" cell.getCellFormula]; +# type_of_cell = ctype (4); +# if (~jerror) +# warning ("Java errors in worksheet formulas (converted to string)"); +# endif +# ++jerror; +# end + case ctype(4) # 3 Blank + # Blank; ignore until further notice + case ctype(5) # 4 Boolean + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getBooleanCellValue (); + otherwise # 5 Error + # Error; ignore + endswitch + endif + endif + endfor + endif + endfor + + if (jerror > 0) printf ("%d Java formula evalation errors\n", jerror); endif + + # Crop rawarr from empty outer rows & columns like Excel does + emptr = cellfun('isempty', rawarr); + irowt = 1; + while (all (emptr(irowt, :))), irowt++; endwhile + irowb = nrows; + while (all (emptr(irowb, :))), irowb--; endwhile + icoll = 1; + while (all (emptr(:, icoll))), icoll++; endwhile + icolr = ncols; + while (all (emptr(:, icolr))), icolr--; endwhile + # Crop textarray + rawarr = rawarr(irowt:irowb, icoll:icolr); + status = 1; + + xls.limits = [lcol+icoll, lcol+icolr; firstrow+irowt, firstrow+irowb]; + +endfunction + + +#================================================================================== +## Copyright (C) 2009 Philip Nienhuis <prnienhuis at users.sf.net> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jxla2oct (@var{xls}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jxla2oct (@var{xls}, @var{wsh}) +## @deftypefnx {Function File} [@var{obj}, @var{rstatus}, @var{xls} ] = xls2jxla2oct (@var{xls}, @var{wsh}, @var{range}) +## Get cell contents in @var{range} in worksheet @var{wsh} in an Excel +## file pointed to in struct @var{xls} into the cell array @var{obj}. +## @var{range} can be a range or just the top left cell of the range. +## +## xls2jxla2oct should not be invoked directly but rather through xls2oct. +## +## Examples: +## +## @example +## [Arr, status, xls] = xls2jxla2oct (xls, 'Second_sheet', 'B3:AY41'); +## B = xls2jxla2oct (xls, 'Second_sheet'); +## @end example +## +## @seealso xls2oct, oct2xls, xlsopen, xlsclose, xlsread, xlswrite, oct2jxla2xls +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-12-04 +## Last updated 2009-12-11 + +function [ rawarr, xls, status ] = xls2jxla2oct (xls, wsh, cellrange=[]) + + persistent ctype; + if (isempty (ctype)) + ctype = cell (11, 1); + # Get enumerated cell types. Beware as they start at 0 not 1 + ctype(1,1) = (java_get ('jxl.CellType', 'BOOLEAN')).toString (); + ctype(2,1) = (java_get ('jxl.CellType', 'BOOLEAN_FORMULA')).toString (); + ctype(3,1) = (java_get ('jxl.CellType', 'DATE')).toString (); + ctype(4,1) = (java_get ('jxl.CellType', 'DATE_FORMULA')).toString (); + ctype(5,1) = (java_get ('jxl.CellType', 'EMPTY')).toString (); + ctype(6,1) = (java_get ('jxl.CellType', 'ERROR')).toString (); + ctype(7,1) = (java_get ('jxl.CellType', 'FORMULA_ERROR')).toString (); + ctype(8,1) = (java_get ('jxl.CellType', 'NUMBER')).toString (); + ctype(9,1) = (java_get ('jxl.CellType', 'LABEL')).toString (); + ctype(10,1) = (java_get ('jxl.CellType', 'NUMBER_FORMULA')).toString (); + ctype(11,1) = (java_get ('jxl.CellType', 'STRING_FORMULA')).toString (); + endif + + status = 0; + + # Check if xls struct pointer seems valid + test1 = ~isfield (xls, "xtype"); + test1 = test1 || ~isfield (xls, "workbook"); + test1 = test1 || ~strcmp (char (xls.xtype), 'JXL'); + test1 = test1 || isempty (xls.workbook); + test1 = test1 || isempty (xls.app); + if test1 + error ("Invalid xls file struct"); + else + wb = xls.workbook; + endif + + # Check if requested worksheet exists in the file & if so, get pointer + nr_of_sheets = wb.getNumberOfSheets (); + shnames = char (wb.getSheetNames ()); + if (isnumeric (wsh)) + if (wsh > nr_of_sheets), error (sprintf ("Worksheet # %d bigger than nr. of sheets (%d) in file %s", wsh, nr_of_sheets, xls.filename)); endif + sh = wb.getSheet (wsh - 1); # POI sheet count 0-based + printf ("(Reading from worksheet %s)\n", shnames {wsh}); + else + sh = wb.getSheet (wsh); + if (isempty (sh)), error (sprintf ("Worksheet %s not found in file %s", wsh, xls.filename)); endif + end + + # Check ranges + firstrow = 0; + lcol = 0; + + if (isempty (cellrange)) + nrows = sh.getRows (); + lastrow = nrows - 1; + ncols = sh.getColumns (); + trow = firstrow; + rcol = ncols - 1; + else + # Translate range to HSSF POI row & column numbers + [dummy, nrows, ncols, trow, lcol] = parse_sp_range (cellrange); + firstrow = max (trow-1, firstrow); + lastrow = firstrow + nrows - 1; + lcol = lcol - 1; # POI rows & column # 0-based + endif + + # Read contents into rawarr + rawarr = cell (nrows, ncols); # create placeholder + for jj = lcol : lcol+ncols-1 + for ii = firstrow:lastrow + cell = sh.getCell (jj, ii); + type_of_cell = char (cell.getType ()); + switch type_of_cell + case ctype {1, 1} + # Boolean + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {2, 1} + # Boolean formula + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {3, 1} + # Date + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {4, 1} + # Date Formula + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {5, 1} + # Empty. Nothing to do here + case ctype {6, 1} + # Error. Nothing to do here + case ctype {7, 1} + # Formula Error. Nothing to do here + case ctype {8, 1} + # Number + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {9, 1} + # String + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getString (); + case ctype {10, 1} + # NumericalFormula + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getValue (); + case ctype {11, 1} + # String Formula + rawarr (ii+1-firstrow, jj+1-lcol) = cell.getString (); + endswitch + endfor + endfor + + # Crop rawarr from empty outer rows & columns just like Excel does + emptr = cellfun('isempty', rawarr); + irowt = 1; + while (all (emptr(irowt, :))), irowt++; endwhile + irowb = nrows; + while (all (emptr(irowb, :))), irowb--; endwhile + icoll = 1; + while (all (emptr(:, icoll))), icoll++; endwhile + icolr = ncols; + while (all (emptr(:, icolr))), icolr--; endwhile + # Crop textarray + rawarr = rawarr(irowt:irowb, icoll:icolr); + status = 1; + + xls.limits = [lcol+icoll, lcol+icolr; firstrow+irowt, firstrow+irowb]; + +endfunction + Modified: trunk/octave-forge/main/io/inst/xlsfinfo.m =================================================================== --- trunk/octave-forge/main/io/inst/xlsfinfo.m 2009-12-30 15:10:35 UTC (rev 6681) +++ trunk/octave-forge/main/io/inst/xlsfinfo.m 2009-12-30 15:50:56 UTC (rev 6682) @@ -54,7 +54,7 @@ ## Author: Philip Nienhuis <prn...@us...> ## Created: 2009-10-27 -## Latest update (Java / POI / xlsopen): 2009-12-11 +## Latest update (Java / POI / xlsopen): 2009-12-30 function [ filetype, sh_names, fformat ] = xlsfinfo (filename) @@ -81,7 +81,7 @@ endfor if (ws_cnt > 0 || ch_cnt > 0) fformat = "xlWorkbookNormal"; endif - elseif (strcmp(xls.xtype, 'POI')) + elseif (strcmp (xls.xtype, 'POI')) sh_cnt = xls.workbook.getNumberOfSheets(); sh_names = cell (sh_cnt, 2); for ii=1:sh_cnt @@ -92,7 +92,7 @@ endfor if (sh_cnt > 0) fformat = "xlWorkbookNormal"; endif - elseif (strcmp(xls.xtype, 'JXL')) + elseif (strcmp (xls.xtype, 'JXL')) sh_cnt = xls.workbook.getNumberOfSheets (); sh_names = cell (sh_cnt, 2); sh_names(:,1) = char (xls.workbook.getSheetNames ()); @@ -103,6 +103,9 @@ # elseif <Other Excel interfaces below> + else + error (sprintf ("xlsfinfo: unknown Excel .xls interface - %s.", xls.xtype)); + endif xlsclose (xls); Modified: trunk/octave-forge/main/io/inst/xlsopen.m =================================================================== --- trunk/octave-forge/main/io/inst/xlsopen.m 2009-12-30 15:10:35 UTC (rev 6681) +++ trunk/octave-forge/main/io/inst/xlsopen.m 2009-12-30 15:50:56 UTC (rev 6682) @@ -29,10 +29,11 @@ ## are referred to as COM, POI and JXL, resp., and are preferred in that ## order by default (depending on their presence). ## -## @var{filename} must be a valid .xls Excel file name. If @var{filename} -## does not contain any directory path, the file is saved in the current -## directory. (Support for .xlsx (Excel 2007 OOXML) will be added later, based -## on Java and Apache POI.) +## @var{filename} should be a valid .xls Excel file name; but if you use the +## COM interface you can specify any extension that your installed Excel version +## can read AND write. If @var{filename} does not contain any directory path, +## the file is saved in the current directory. (Support for .xlsx (Excel 2007 +## OOXML) based on Java and Apache POI will be added later). ## ## If @var{readwrite} is set to 0 (default value) or omitted, the Excel file ## is opened for reading. If @var{readwrite} is set to True or 1, an Excel @@ -61,7 +62,7 @@ ## Author: Philip Nienhuis ## Created: 2009-11-29 -## Last updated 2009-12-07 +## Last updated 2009-12-30 function [ xls ] = xlsopen (filename, xwrite=0, reqinterface=[]) @@ -121,18 +122,8 @@ xlsinterfaces = getxlsinterfaces (xlsinterfaces); -# Supported interfaces determined; now check Excel file type. - +# Supported interfaces determined; Excel file type check moved to seperate interfaces. chk1 = strcmp (tolower (filename(end-3:end)), '.xls'); -# chk2 = strcmp (tolower (filename(end-4:end)), '.xlsx'); -# if (xlsinterfaces.POI) -# if ~(chk1 || chk2) -# error ("xlsopen: only .xls or .xlsx files can be processed reliably"); -# end -# elseif (~chk1) - if (~chk1) - error ("Currently xls2oct can only read reliably from .xls files") - endif xls = struct ("xtype", 'NONE', "app", [], "filename", [], "workbook", [], "changed", 0, "limits", []); @@ -154,6 +145,9 @@ xls.filename = filename; elseif (xlsinterfaces.JXL) + if (~chk1) + error ("Currently xls2oct / JXL can only read reliably from .xls files") + endif xls.xtype = 'JXL'; xlsin = java_new ('java.io.File', filename); if (xwrite == 2) @@ -168,6 +162,9 @@ xls.filename = filename; elseif (xlsinterfaces.POI) + if (~chk1) + error ("Currently xls2oct / POI can only read reliably from .xls files") + endif xls.xtype = 'POI'; # Get handle to workbook if (xwrite == 2) @@ -252,7 +249,7 @@ ## Author: Philip Nienhuis ## Created: 2009-11-29 -## Last updated 2009-12-11 +## Last updated 2009-12-27 function [xlsinterfaces] = getxlsinterfaces (xlsinterfaces) @@ -303,7 +300,7 @@ warning ("\n Java support OK but not all required classes (.jar) in classpath"); endif catch - # COM non-existent + # POI non-existent end_try_catch endif @@ -330,7 +327,7 @@ warning ("\nJava support OK but required classes (.jar) not all in classpath"); endif catch - # COM non-existent + # JXL non-existent end_try_catch endif Modified: trunk/octave-forge/main/io/inst/xlsread.m =================================================================== --- trunk/octave-forge/main/io/inst/xlsread.m 2009-12-30 15:10:35 UTC (rev 6681) +++ trunk/octave-forge/main/io/inst/xlsread.m 2009-12-30 15:50:56 UTC (rev 6682) @@ -102,10 +102,9 @@ ## ## @example ## [An, Tn, Ra, limits] = xlsread ('Sales2009.xls', 'Third_sheet'); -## (which returns the numeric contents in range C3:AB40 in worksheet -## 'Third_sheet' in file test4.xls into array An, the text data into -## array Tn, the raw cell data into cell array Ra and the ranges from -## where the actual data came in limits) +## (which returns all data in worksheet 'Third_sheet' in file test4.xls +## into array An, the text data into array Tn, the raw cell data into +## cell array Ra and the ranges from where the actual data came in limits) ## @end example ## ## @seealso xlswrite, xlsopen, xls2oct, xlsclose, xlsfinfo, oct2xls @@ -114,7 +113,7 @@ ## Author: Philip Nienhuis ## Created: 2009-10-16 -## Latest update: 2009-12-11 +## Latest update: 2009-12-29 function [ numarr, txtarr, rawarr, lims ] = xlsread (fn, wsh, datrange, reqintf=[]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |