X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=octave_packages%2Fio-1.0.19%2Fxlsopen.m;fp=octave_packages%2Fio-1.0.19%2Fxlsopen.m;h=13c83e95ad0342a038545e86eb9310e089f24e8d;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hp=0000000000000000000000000000000000000000;hpb=1705066eceaaea976f010f669ce8e972f3734b05;p=CreaPhase.git diff --git a/octave_packages/io-1.0.19/xlsopen.m b/octave_packages/io-1.0.19/xlsopen.m new file mode 100644 index 0000000..13c83e9 --- /dev/null +++ b/octave_packages/io-1.0.19/xlsopen.m @@ -0,0 +1,647 @@ +## Copyright (C) 2009,2010,2011,2012 Philip Nienhuis +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} @var{xls} = xlsopen (@var{filename}) +## @deftypefnx {Function File} @var{xls} = xlsopen (@var{filename}, @var{readwrite}) +## @deftypefnx {Function File} @var{xls} = xlsopen (@var{filename}, @var{readwrite}, @var{reqintf}) +## Get a pointer to an Excel spreadsheet in the form of return argument +## (file pointer struct) @var{xls}. After processing the spreadsheet, +## the file pointer must be explicitly closed by calling xlsclose(). +## +## Calling xlsopen without specifying a return argument is fairly useless! +## +## To make this function work at all, you need MS-Excel (95 - 2003), and/or +## the Java package >= 1.2.8 plus Apache POI >= 3.5 and/or JExcelAPI and/or +## OpenXLS and/or OpenOffice.org (or clones) installed on your computer + +## proper javaclasspath set. These interfaces are referred to as COM, POI, +## JXL, OXS, and UNO, resp., and are preferred in that order by default +## (depending on their presence). +## For OOXML support, in addition to Apache POI support you also need the +## following jars in your javaclasspath: poi-ooxml-schemas-3.5.jar, +## xbean.jar and dom4j-1.6.1.jar (or later versions). Later OpenOffice.org +## versions (UNO) have support for OOXML as well. +## Excel'95 spreadsheets can only be read by JExcelAPI and OpenOffice.org. +## +## @var{filename} should be a valid .xls or xlsx Excel file name (including +## extension). But if you use the COM interface you can specify any extension +## that your installed Excel version can read AND write; the same goes for UNO +## (OpenOffice.org). Using the other Java interfaces, only .xls or .xlsx are +## allowed. If @var{filename} does not contain any directory path, the file +## is saved in the current directory. +## +## 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 +## file is opened (or created) for reading & writing. +## +## Optional input argument @var{reqintf} can be used to override the Excel +## interface that otherwise is automatically selected by xlsopen. Currently +## implemented interfaces (in order of preference) are 'COM' (Excel/COM), +## 'POI' (Java/Apache POI), 'JXL' (Java/JExcelAPI), 'OXS' (Java/OpenXLS), or +## 'UNO' (Java/OpenOffice.org - EXPERIMENTAL!). +## In most situations this parameter is unneeded as xlsopen automatically +## selects the most useful interface present. +## +## Beware: Excel invocations may be left running invisibly in case of COM +## errors or forgetting to close the file pointer. Similarly for OpenOffice.org +## which may even prevent Octave from being closed. +## +## Examples: +## +## @example +## xls = xlsopen ('test1.xls'); +## (get a pointer for reading from spreadsheet test1.xls) +## +## xls = xlsopen ('test2.xls', 1, 'POI'); +## (as above, indicate test2.xls will be written to; in this case using Java +## and the Apache POI interface are requested) +## @end example +## +## @seealso {xlsclose, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo} +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-11-29 +## Updates: +## 2010-01-03 Added OOXML support +## 2010-01-10 Changed (java) interface preference order to COM->POI->JXL +## 2010-01-16 Removed echoeing debug info in POI stanza +## 2010-03-01 Removed javaclasspath check for rt.jar +## 2010-03-14 Fixed check on xwrite flag lines 204+, if xlsopen fails xls ptr +## should be [] +## 2010-08-25 Improved help text +## 2010-09-27 Improved POI help message for unrecognized .xls format to hint for BIFF5/JXL +## 2010-10-20 Improved code for tracking changes to new/existing files +## '' Lots of code cleanup, improved error checking and catching +## '' Implemented fallback to JXL if POI can't read a file. +## 2010-10-30 More fine-grained file existence/writable checks +## 2010-11-01 Added .Application.DisplayAlerts=0 in COM section to avoid Excel pop-ups +## 2010-11-05 Option for multiple requested interface types (cell array) +## '' Bug fix: JXL fallback from POI for BIFF5 is only useful for reading +## 2010-11-05 Slight change to reporting to screen +## 2010-11-08 Tested with POI 3.7 (OK) +## 2010-11-10 Texinfo header updated +## 2010-12-01 Small bugfix - reset xlssupport in l. 102 +## 2010-12-06 Textual changes to info header +## 2011-03-26 OpenXLS support added +## 2011-05-18 Experimental UNO support added, incl. creating new spreadsheets +## 2011-05-22 Textual changes in header +## 2011-05-29 Cleanup of comments & messages +## 2011-09-03 Reset chkintf to [] if no xls support was discovered (to allow +## rediscovery of interfaces between xlsopen calls, e.g. javaclasspath changes) +## 2011-09-08 Minor code cleanup +## 2012-01-26 Fixed "seealso" help string +## 2012-06-06 Improved interface detection logic. No more messages if same interface is +## requested & used consecutively +## 2012-06-07 Fixed mixed-up lastintf assignments for POI and JXL +## +## Latest subfunction update: 2012-06-06 + +function [ xls ] = xlsopen (filename, xwrite=0, reqinterface=[]) + + persistent xlsinterfaces; persistent chkintf; persistent lastintf; + # xlsinterfaces. = [] (not yet checked), 0 (found to be unsupported) or 1 (OK) + if (isempty (chkintf)); + chkintf = 1; + xlsinterfaces = struct ('COM', [], 'POI', [], 'JXL', [], 'OXS', [], 'UNO', []); + endif + if (isempty (lastintf)) + lastintf = "---"; + endif + + xlssupport = 0; + + if (nargout < 1) + usage ("XLS = xlsopen (Xlfile [, Rw] [, reqintf]). But no return argument specified!"); + endif + + if (~(islogical (xwrite) || isnumeric (xwrite))) + usage ("Numerical or logical value expected for arg # 2") + endif + + if (~isempty (reqinterface)) + if ~(ischar (reqinterface) || iscell (reqinterface)), usage ("Arg # 3 not recognized"); endif + # Turn arg3 into cell array if needed + if (~iscell (reqinterface)), reqinterface = {reqinterface}; endif + ## Check if previously used interface matches a requested interface + if (isempty (regexpi (reqinterface, lastintf, 'once'){1})) + ## New interface requested + xlsinterfaces.COM = 0; xlsinterfaces.POI = 0; xlsinterfaces.JXL = 0; + xlsinterfaces.OXS = 0; xlsinterfaces.UNO = 0; + for ii=1:numel (reqinterface) + reqintf = toupper (reqinterface {ii}); + # Try to invoke requested interface(s) for this call. Check if it + # is supported anyway by emptying the corresponding var. + if (strcmpi (reqintf, 'COM')) + xlsinterfaces.COM = []; + elseif (strcmpi (reqintf, 'POI')) + xlsinterfaces.POI = []; + elseif (strcmpi (reqintf, 'JXL')) + xlsinterfaces.JXL = []; + elseif (strcmpi (reqintf, 'OXS')) + xlsinterfaces.OXS = []; + elseif (strcmpi (reqintf, 'UNO')) + xlsinterfaces.UNO = []; + else + usage (sprintf ("Unknown .xls interface \"%s\" requested. Only COM, POI, JXL, OXS or UNO supported\n", reqinterface{})); + endif + endfor + printf ("Checking requested interface(s):\n"); + xlsinterfaces = getxlsinterfaces (xlsinterfaces); + # Well, is/are the requested interface(s) supported on the system? + # FIXME check for multiple interfaces + xlsintf_cnt = 0; + for ii=1:numel (reqinterface) + if (~xlsinterfaces.(toupper (reqinterface{ii}))) + # No it aint + printf ("%s is not supported.\n", upper (reqinterface{ii})); + else + ++xlsintf_cnt; + endif + endfor + # Reset interface check indicator if no requested support found + if (~xlsintf_cnt) + chkintf = []; + xls = []; + return + endif + endif + endif + + # Var xwrite is really used to avoid creating files when wanting to read, or + # not finding not-yet-existing files when wanting to write. + + # Check if Excel file exists. Adapt file open mode for readwrite argument + if (xwrite), fmode = 'r+b'; else fmode = 'rb'; endif + fid = fopen (filename, fmode); + if (fid < 0) # File doesn't exist... + if (~xwrite) # ...which obviously is fatal for reading... + error ( sprintf ("File %s not found\n", filename)); + else # ...but for writing, we need more info: + fid = fopen (filename, 'rb'); # Check if it exists at all... + if (fid < 0) # File didn't exist yet. Simply create it + printf ("Creating file %s\n", filename); + xwrite = 3; + else # File exists, but is not writable => Error + fclose (fid); # Do not forget to close the handle neatly + error (sprintf ("Write mode requested but file %s is not writable\n", filename)) + endif + endif + else + # Close file anyway to avoid COM or Java errors + fclose (fid); + endif + + # Check for the various Excel interfaces. No problem if they've already + # been checked, getxlsinterfaces (far below) just returns immediately then. + xlsinterfaces = getxlsinterfaces (xlsinterfaces); + + # Supported interfaces determined; Excel file type check moved to seperate interfaces. + chk1 = strcmpi (filename(end-3:end), '.xls'); # Regular (binary) BIFF + chk2 = strcmpi (filename(end-4:end-1), '.xls'); # Zipped XML / OOXML + + # Initialize file ptr struct + xls = struct ("xtype", 'NONE', "app", [], "filename", [], "workbook", [], "changed", 0, "limits", []); + + # Keep track of which interface is selected + xlssupport = 0; + + # Interface preference order is defined below: currently COM -> POI -> JXL -> OXS -> UNO + if (xlsinterfaces.COM && ~xlssupport) + # Excel functioning has been tested above & file exists, so we just invoke it + app = actxserver ("Excel.Application"); + try # Because Excel itself can still crash on file formats etc. + app.Application.DisplayAlerts = 0; + if (xwrite < 2) + # Open workbook + wb = app.Workbooks.Open (canonicalize_file_name (filename)); + elseif (xwrite > 2) + # Create a new workbook + wb = app.Workbooks.Add (); + ### Uncommenting the below statement can be useful in multi-user environments. + ### Be sure to uncomment correspondig stanza in xlsclose to avoid zombie Excels + # wb.SaveAs (canonicalize_file_name (filename)) + endif + xls.app = app; + xls.xtype = 'COM'; + xls.workbook = wb; + xls.filename = filename; + xlssupport += 1; + lastintf = 'COM'; + catch + warning ( sprintf ("ActiveX error trying to open or create file %s\n", filename)); + app.Application.DisplayAlerts = 1; + app.Quit (); + delete (app); + end_try_catch + endif + + if (xlsinterfaces.POI && ~xlssupport) + if ~(chk1 || chk2) + error ("Unsupported file format for Apache POI.") + endif + # Get handle to workbook + try + if (xwrite > 2) + if (chk1) + wb = java_new ('org.apache.poi.hssf.usermodel.HSSFWorkbook'); + elseif (chk2) + wb = java_new ('org.apache.poi.xssf.usermodel.XSSFWorkbook'); + endif + xls.app = 'new_POI'; + else + xlsin = java_new ('java.io.FileInputStream', filename); + wb = java_invoke ('org.apache.poi.ss.usermodel.WorkbookFactory', 'create', xlsin); + xls.app = xlsin; + endif + xls.xtype = 'POI'; + xls.workbook = wb; + xls.filename = filename; + xlssupport += 2; + lastintf = 'POI'; + catch + clear xlsin; + if (xlsinterfaces.JXL) + printf ('Couldn''t open file %s using POI; trying Excel''95 format with JXL...\n', filename); + endif + end_try_catch + endif + + if (xlsinterfaces.JXL && ~xlssupport) + if (~chk1) + error ("JXL can only read reliably from .xls files") + endif + try + xlsin = java_new ('java.io.File', filename); + if (xwrite > 2) + # Get handle to new xls-file + wb = java_invoke ('jxl.Workbook', 'createWorkbook', xlsin); + else + # Open existing file + wb = java_invoke ('jxl.Workbook', 'getWorkbook', xlsin); + endif + xls.xtype = 'JXL'; + xls.app = xlsin; + xls.workbook = wb; + xls.filename = filename; + xlssupport += 4; + lastintf = 'JXL'; + catch + clear xlsin; + if (xlsinterfaces.POI) + printf ('... No luck with JXL either, unsupported file format.\n', filename); + endif + end_try_catch + endif + + if (xlsinterfaces.OXS && ~xlssupport) + if (~chk1) + error ("OXS can only read from .xls files") + endif + try + wb = javaObject ('com.extentech.ExtenXLS.WorkBookHandle', filename); + xls.xtype = 'OXS'; + xls.app = 'void - OpenXLS'; + xls.workbook = wb; + xls.filename = filename; + xlssupport += 8; + lastintf = 'OXS'; + catch + printf ('Unsupported file format for OpenXLS - %s\n'); + end_try_catch + endif + + if (xlsinterfaces.UNO && ~xlssupport) + # First, the file name must be transformed into a URL + if (~isempty (strmatch ("file:///", filename)) || ~isempty (strmatch ("http:///", filename))... + || ~isempty (strmatch ("ftp:///", filename)) || ~isempty (strmatch ("www:///", filename))) + # Seems in proper shape for OOo (at first sight) + else + # Transform into URL form + fname = canonicalize_file_name (strsplit (filename, filesep){end}); + # On Windows, change backslash file separator into forward slash + if (strcmp (filesep, "\\")) + tmp = strsplit (fname, filesep); + flen = numel (tmp); + tmp(2:2:2*flen) = tmp; + tmp(1:2:2*flen) = '/'; + fname = [ tmp{:} ]; + endif + filename = [ 'file://' fname ]; + endif + try + xContext = java_invoke ("com.sun.star.comp.helper.Bootstrap", "bootstrap"); + xMCF = xContext.getServiceManager (); + oDesktop = xMCF.createInstanceWithContext ("com.sun.star.frame.Desktop", xContext); + # Workaround for .queryInterface(): + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XComponentLoader'); + aLoader = oDesktop.queryInterface (unotmp); + # Some trickery as Octave Java cannot create initialized arrays + lProps = javaArray ('com.sun.star.beans.PropertyValue', 1); + lProp = java_new ('com.sun.star.beans.PropertyValue', "Hidden", 0, true, []); + lProps(1) = lProp; + if (xwrite > 2) + xComp = aLoader.loadComponentFromURL ("private:factory/scalc", "_blank", 0, lProps); + else + xComp = aLoader.loadComponentFromURL (filename, "_blank", 0, lProps); + endif + # Workaround for .queryInterface(): + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XSpreadsheetDocument'); + xSpdoc = xComp.queryInterface (unotmp); + # save in ods struct: + xls.xtype = 'UNO'; + xls.workbook = xSpdoc; # Needed to be able to close soffice in odsclose() + xls.filename = filename; + xls.app.xComp = xComp; # Needed to be able to close soffice in odsclose() + xls.app.aLoader = aLoader; # Needed to be able to close soffice in odsclose() + xls.odfvsn = 'UNO'; + xlssupport += 16; + lastintf = 'UNO'; + catch + error ('Couldn''t open file %s using UNO', filename); + end_try_catch + endif + + # if + # ---- other interfaces + # endif + + # Rounding up. If none of the xlsinterfaces is supported we're out of luck. + if (~xlssupport) + if (isempty (reqinterface)) + printf ("None.\n"); + warning ("No support for Excel .xls I/O"); + else + warning ("File type not supported by %s %s %s %s %s", reqinterface{:}); + endif + xls = []; + # Reset found interfaces for re-testing in the next call. Add interfaces if needed. + chkintf = []; + else + # From here on xwrite is tracked via xls.changed in the various lower + # level r/w routines and it is only used to determine if an informative + # message is to be given when saving a newly created xls file. + xls.changed = xwrite; + + # Until something was written to existing files we keep status "unchanged". + # xls.changed = 0 (existing/only read from), 1 (existing/data added), 2 (new, + # data added) or 3 (pristine, no data added). + if (xls.changed == 1), xls.changed = 0; endif + endif + +endfunction + + +## Copyright (C) 2009,2010,2011,2012 Philip Nienhuis +## +## 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 +## . + +## -*- texinfo -*- +## @deftypefn {Function File} @var{xlsinterfaces} = getxlsinterfaces (@var{xlsinterfaces}) +## Get supported Excel .xls file read/write interfaces from the system. +## Each interface for which the corresponding field is set to empty +## will be checked. So by manipulating the fields of input argument +## @var{xlsinterfaces} it is possible to specify which +## interface(s) should be checked. +## +## Currently implemented interfaces comprise: +## - ActiveX / COM (native Excel in the background) +## - Java & Apache POI +## - Java & JExcelAPI +## - Java & OpenXLS (only JRE >= 1.4 needed) +## - Java & UNO bridge (native OpenOffice.org in background) - EXPERIMENTAL!! +## +## Examples: +## +## @example +## xlsinterfaces = getxlsinterfaces (xlsinterfaces); +## @end example + +## Author: Philip Nienhuis +## Created: 2009-11-29 +## Last updates: +## 2009-12-27 Make sure proper dimensions are checked in parsed javaclasspath +## 2010-09-11 Rearranged code and clarified messages about missing classes +## 2010-09-27 More code cleanup +## 2010-10-20 Added check for minimum Java version (should be >= 6 / 1.6) +## 2010-11-05 Slight change to reporting to screen +## 2011-02-15 Adapted to javaclasspath calling style of java-1.2.8 pkg +## 2011-03-26 OpenXLS support added +## '' Bug fix: javaclasspath change wasn't picked up between calls with req.intf +## 2011-05-18 Experimental UNO support added +## 2011-05-29 Reduced verbosity +## 2011-06-06 Fix for javaclasspath format in *nix w java-1.2.8 pkg +## 2011-06-13 Fixed potentially faulty tests for java classlib presence +## 2011-09-03 Fixed order of xlsinterfaces. statements in Java detection try-catch +## '' Reset tmp1 (always allow interface rediscovery) for empty xlsinterfaces arg +## 2011-09-08 Minor code cleanup +## 2011-09-18 Added temporary warning about UNO interface +## 2012-03-01 Changed UNO warning so that it is suppressed when UNO is not yet chosen +## 2012-03-07 Only check for COM if run on Windows +## 2012-03-21 Print newline if COM found but no Java support +## '' Improved logic for finding out what interfaces to check +## '' Fixed bugs with Java interface checking (tmp1 initialization) +## 2012-06-06 Improved & simplified Java check code + +function [xlsinterfaces] = getxlsinterfaces (xlsinterfaces) + + # tmp1 = [] (not initialized), 0 (No Java detected), or 1 (Working Java found) + persistent tmp1 = []; persistent jcp; # Java class path + persistent uno_1st_time = 0; + + if (isempty (xlsinterfaces.COM) && isempty (xlsinterfaces.POI) && isempty (xlsinterfaces.JXL) + && isempty (xlsinterfaces.OXS) && isempty (xlsinterfaces.UNO)) + # Looks like first call to xlsopen. Check Java support + printf ("Detected XLS interfaces: "); + tmp1 = []; + elseif (isempty (xlsinterfaces.POI) || isempty (xlsinterfaces.JXL) + || isempty (xlsinterfaces.OXS) || isempty (xlsinterfaces.UNO)) + # Can't be first call. Here one of the Java interfaces is requested + if (~tmp1) + # Check Java support again + tmp1 = []; + endif + endif + deflt = 0; + + # Check if MS-Excel COM ActiveX server runs (only on Windows!) + if (isempty (xlsinterfaces.COM)) + xlsinterfaces.COM = 0; + if (ispc) + try + app = actxserver ("Excel.application"); + # If we get here, the call succeeded & COM works. + xlsinterfaces.COM = 1; + # Close Excel. Yep this is inefficient when we need only one r/w action, + # but it quickly pays off when we need to do more with the same file + # (+, MS-Excel code is in OS cache anyway after this call so no big deal) + app.Quit(); + delete(app); + printf ("COM"); + if (deflt), printf ("; "); else, printf ("*; "); deflt = 1; endif + catch + # COM non-existent. Only print message if COM is explicitly requested (tmp1==[]) + if (~isempty (tmp1)) + printf ("ActiveX not working; no Excel installed?\n"); + endif + end_try_catch + endif + endif + + if (isempty (tmp1)) + # Check Java support. First try javaclasspath + try + jcp = javaclasspath ('-all'); # For java pkg > 1.2.7 + if (isempty (jcp)), jcp = javaclasspath; endif # For java pkg < 1.2.8 + # If we get here, at least Java works. Now check for proper version (>= 1.6) + jver = char (java_invoke ('java.lang.System', 'getProperty', 'java.version')); + cjver = strsplit (jver, '.'); + if (sscanf (cjver{2}, '%d') < 6) + warning ("\nJava version might be too old - you need at least Java 6 (v. 1.6.x.x)\n"); + return + endif + # Now check for proper entries in class path. Under *nix the classpath + # must first be split up. In java 1.2.8+ javaclasspath is already a cell array + if (isunix && ~iscell (jcp)); jcp = strsplit (char (jcp), ":"); endif + tmp1 = 1; + catch + # No Java support found + tmp1 = 0; + if (isempty (xlsinterfaces.POI) || isempty (xlsinterfaces.JXL)... + || isempty (xlsinterfaces.OXS) || isempty (xlsinterfaces.UNO)) + # Some or all Java-based interface(s) explicitly requested but no Java support + warning (' No Java support found (no Java JRE? no Java pkg installed AND loaded?'); + endif + # Set Java interfaces to 0 anyway as there's no Java support + xlsinterfaces.POI = 0; + xlsinterfaces.JXL = 0; + xlsinterfaces.OXS = 0; + xlsinterfaces.UNO = 0; + printf ("\n"); + # No more need to try any Java interface + return + end_try_catch + endif + + # Try Java & Apache POI + if (isempty (xlsinterfaces.POI)) + xlsinterfaces.POI = 0; + # Check basic .xls (BIFF8) support + jpchk1 = 0; entries1 = {"poi-3", "poi-ooxml-3"}; + # Only under *nix we might use brute force: e.g., strfind (classname, classpath); + # under Windows we need the following more subtle, platform-independent approach: + for ii=1:length (jcp) + for jj=1:length (entries1) + if (isempty (strfind (tolower (jcp{ii}), entries1{jj}))), ++jpchk1; endif + endfor + endfor + if (jpchk1 > 1) + xlsinterfaces.POI = 1; + printf ("POI"); + endif + # Check OOXML support + jpchk2 = 0; entries2 = {"xbean", "poi-ooxml-schemas", "dom4j"}; + for ii=1:length (jcp) + for jj=1:length (entries2) + if (isempty (strfind (lower (jcp{ii}), entries2{jj}))), ++jpchk2; endif + endfor + endfor + if (jpchk2 > 2), printf (" (& OOXML)"); endif + if (xlsinterfaces.POI) + if (deflt), printf ("; "); else, printf ("*; "); deflt = 1; endif + endif + endif + + # Try Java & JExcelAPI + if (isempty (xlsinterfaces.JXL)) + xlsinterfaces.JXL = 0; + jpchk = 0; entries = {"jxl"}; + for ii=1:length (jcp) + for jj=1:length (entries) + if (isempty (strfind (lower (jcp{ii}), entries{jj}))), ++jpchk; endif + endfor + endfor + if (jpchk > 0) + xlsinterfaces.JXL = 1; + printf ("JXL"); + if (deflt), printf ("; "); else, printf ("*; "); deflt = 1; endif + endif + endif + + # Try Java & OpenXLS + if (isempty (xlsinterfaces.OXS)) + xlsinterfaces.OXS = 0; + jpchk = 0; entries = {"openxls"}; + for ii=1:length (jcp) + for jj=1:length (entries) + if (isempty (strfind (lower (jcp{ii}), entries{jj}))), ++jpchk; endif + endfor + endfor + if (jpchk > 0) + xlsinterfaces.OXS = 1; + printf ("OXS"); + if (deflt), printf ("; "); else, printf ("*; "); deflt = 1; endif + endif + endif + + # Try Java & UNO + if (isempty (xlsinterfaces.UNO)) + xlsinterfaces.UNO = 0; + # entries0(1) = not a jar but a directory (<00o_install_dir/program/>) + jpchk = 0; entries = {'program', 'unoil', 'jurt', 'juh', 'unoloader', 'ridl'}; + for jj=1:numel (entries) + for ii=1:numel (jcp) + jcplst = strsplit (jcp{ii}, filesep); + jcpentry = jcplst {end}; + if (~isempty (strfind (lower (jcpentry), lower (entries{jj})))); ++jpchk; endif + endfor + endfor + if (jpchk >= numel (entries)) + xlsinterfaces.UNO = 1; + printf ('UNO'); + if (deflt), printf ("; "); else, printf ("*; "); deflt = 1; uno_1st_time = min (++uno_1st_time, 2); endif + endif + endif + + # ---- Other interfaces here, similar to the ones above + + if (deflt), printf ("(* = active interface)\n"); endif + + ## FIXME the below stanza should be dropped once UNO is stable. + # Echo a suitable warning about experimental status: + if (uno_1st_time == 1) + ++uno_1st_time; + printf ("\nPLEASE NOTE: UNO (=OpenOffice.org-behind-the-scenes) is EXPERIMENTAL\n"); + printf ("After you've opened a spreadsheet file using the UNO interface,\n"); + printf ("xlsclose on that file will kill ALL OpenOffice.org invocations,\n"); + printf ("also those that were started outside and/or before Octave!\n"); + printf ("Trying to quit Octave w/o invoking xlsclose will only hang Octave.\n\n"); + endif + +endfunction