X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?p=CreaPhase.git;a=blobdiff_plain;f=octave_packages%2Fio-1.0.19%2Fxlsclose.m;fp=octave_packages%2Fio-1.0.19%2Fxlsclose.m;h=c38fd80d72b02572654cc445c9bd2b3c9051d5db;hp=0000000000000000000000000000000000000000;hb=f5f7a74bd8a4900f0b797da6783be80e11a68d86;hpb=1705066eceaaea976f010f669ce8e972f3734b05 diff --git a/octave_packages/io-1.0.19/xlsclose.m b/octave_packages/io-1.0.19/xlsclose.m new file mode 100644 index 0000000..c38fd80 --- /dev/null +++ b/octave_packages/io-1.0.19/xlsclose.m @@ -0,0 +1,278 @@ +## 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 3 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 . + +## -*- texinfo -*- +## @deftypefn {Function File} [@var{xls}] = xlsclose (@var{xls}) +## @deftypefnx {Function File} [@var{xls}] = xlsclose (@var{xls}, @var{filename}) +## @deftypefnx {Function File} [@var{xls}] = xlsclose (@var{xls}, "FORCE") +## Close the Excel spreadsheet pointed to in struct @var{xls}, if needed +## write the file to disk. Based on information contained in @var{xls}, +## xlsclose will determine if the file should be written to disk. +## +## If no errors occured during writing, the xls file pointer struct will be +## reset and -if COM interface was used- ActiveX/Excel will be closed. +## However if errors occurred, the file pinter will be untouched so you can +## clean up before a next try with xlsclose(). +## Be warned that until xlsopen is called again with the same @var{xls} pointer +## struct, hidden Excel or Java applications with associated (possibly large) +## memory chunks are kept in memory, taking up resources. +## If (string) argument "FORCE" is supplied, the file pointer will be reset +## regardless, whether the possibly modified file has been saved successfully +## or not. Hidden Excel (COM) or OpenOffice.org (UNO) invocations may live on, +## possibly even impeding proper shutdown of Octave. +## +## @var{filename} can be used to write changed spreadsheet files to +## an other file than opened with xlsopen(); unfortunately this doesn't work +## with JXL (JExcelAPI) interface. +## +## You need MS-Excel (95 - 2010), 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, to make this +## function work at all. +## +## @var{xls} must be a valid pointer struct made by xlsopen() in the same +## octave session. +## +## Examples: +## +## @example +## xls1 = xlsclose (xls1); +## (Close spreadsheet file pointed to in pointer struct xls1; xls1 is reset) +## @end example +## +## @seealso {xlsopen, xlsread, xlswrite, xls2oct, oct2xls, xlsfinfo} +## +## @end deftypefn + +## Author: Philip Nienhuis +## Created: 2009-11-29 +## Updates: +## 2010-01-03 (checked OOXML support) +## 2010-08-25 See also: xlsopen (instead of xlsclose) +## 2010-10-20 Improved tracking of file changes and need to write it to disk +## 2010-10-27 Various changes to catch errors when writing to disk; +## " Added input arg "keepxls" for use with xlswrite.m to save the +## " untouched file ptr struct in case of errors rather than wipe it +## 2010-11-12 Replaced 'keepxls' by new filename arg; catch write errors and +## always keep file pointer in case of write errors +## 2011-03-26 Added OpenXLS support +## 2011-05-18 Added experimental UNO support, incl. saving newly created files +## 2011-09-08 Bug fix in check for filename input arg +## 2012-01-26 Fixed "seealso" help string + +function [ xls ] = xlsclose (xls, varargs) + + force = 0; + + if (nargin > 1) + for ii=2:nargin + if (strcmp (lower (varargin{ii}), "force")) + # Close .ods anyway even if write errors occur + force = 1; + elseif (~isempty (strfind (tolower (varargin{ii}), '.'))) + # Apparently a file name + if (xls.changed == 0 || xls.changed > 2) + printf ("File %s wasn't changed, new filename ignored.", xls.filename); + elseif (strcmp (xls.xtype, 'JXL')) + error ("JXL doesn't support changing filename, new filename ignored."); + elseif ~((strcmp (xls.xtype, 'COM') || strcmp (xls.xtype, 'UNO')) && isempty (strfind ( lower (filename), '.xls'))) + # Excel/ActiveX && OOo (UNO bridge) will write any valid filetype; POI/JXL/OXS need .xls[x] + error ('.xls or .xlsx extension lacking in filename %s', filename); + else + ### For multi-user environments, uncomment below AND relevant stanza in xlsopen + # In case of COM, be sure to first close the open workbook + #if (strcmp (xls.xtype, 'COM')) + # xls.app.Application.DisplayAlerts = 0; + # xls.workbook.close(); + # xls.app.Application.DisplayAlerts = 0; + #endif + if (strcmp (xls.xtype, 'UNO')) + # If needed, turn filename into 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) = '/'; + filename = [ 'file://' tmp{:} ]; + endif + endif + endif + # Preprocessing / -checking ready. Assign filename arg to file ptr struct + xls.filename = filename; + endif + endif + endfor + endif + + if (strcmp (xls.xtype, 'COM')) + # If file has been changed, write it out to disk. + # + # Note: COM / VB supports other Excel file formats as FileFormatNum: + # 4 = .wks - Lotus 1-2-3 / Microsoft Works + # 6 = .csv + # -4158 = .txt + # 36 = .prn + # 50 = .xlsb - xlExcel12 (Excel Binary Workbook in 2007 with or without macro's) + # 51 = .xlsx - xlOpenXMLWorkbook (without macro's in 2007) + # 52 = .xlsm - xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007) + # 56 = .xls - xlExcel8 (97-2003 format in Excel 2007) + # (see Excel Help, VB reference, Enumerations, xlFileType) + + # xls.changed = 0: no changes: just close; + # 1: existing file with changes: save, close. + # 2: new file with data added: save, close + # 3: new file, no added added (empty): close & delete on disk + + xls.app.Application.DisplayAlerts = 0; + try + if (xls.changed > 0 && xls.changed < 3) + if (xls.changed == 2) + # Probably a newly created, or renamed, Excel file + printf ("Saving file %s ...\n", xls.filename); + xls.workbook.SaveAs (canonicalize_file_name (xls.filename)); + elseif (xls.changed == 1) + # Just updated existing Excel file + xls.workbook.Save (); + endif + xls.changed = 0; + xls.workbook.Close (canonicalize_file_name (xls.filename)); + endif + xls.app.Quit (); + delete (xls.workbook); # This statement actually closes the workbook + delete (xls.app); # This statement actually closes down Excel + catch + xls.app.Application.DisplayAlerts = 1; + end_try_catch + + elseif (strcmp (xls.xtype, 'POI')) + if (xls.changed > 0 && xls.changed < 3) + try + xlsout = java_new ("java.io.FileOutputStream", xls.filename); + bufout = java_new ("java.io.BufferedOutputStream", xlsout); + if (xls.changed == 2) printf ("Saving file %s...\n", xls.filename); endif + xls.workbook.write (bufout); + bufout.flush (); + bufout.close (); + xlsout.close (); + xls.changed = 0; + catch +# xlsout.close (); + end_try_catch + endif + + elseif (strcmp (xls.xtype, 'JXL')) + if (xls.changed > 0 && xls.changed < 3) + try + if (xls.changed == 2) printf ("Saving file %s...\n", xls.filename); endif + xls.workbook.write (); + xls.workbook.close (); + if (xls.changed == 3) + # Upon entering write mode, JExcelAPI always makes a disk file + # Incomplete new files (no data added) had better be deleted. + xls.workbook.close (); + delete (xls.filename); + endif + xls.changed = 0; + catch + end_try_catch + endif + + elseif (strcmp (xls.xtype, 'OXS')) + if (xls.changed > 0 && xls.changed < 3) + try + xlsout = java_new ("java.io.FileOutputStream", xls.filename); + bufout = java_new ("java.io.BufferedOutputStream", xlsout); + if (xls.changed == 2) printf ("Saving file %s...\n", xls.filename); endif + xls.workbook.writeBytes (bufout); + xls.workbook.close (); + bufout.flush (); + bufout.close (); + xlsout.close (); + xls.changed = 0; + catch +# xlsout.close (); + end_try_catch + else + xls.workbook.close (); + endif + + elseif (strcmp (xls.xtype, 'UNO')) + # Java & UNO bridge + try + if (xls.changed && xls.changed < 3) + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel'); + xModel = xls.workbook.queryInterface (unotmp); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XModifiable'); + xModified = xModel.queryInterface (unotmp); + if (xModified.isModified ()) + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XStorable'); # isReadonly() ? + xStore = xls.app.xComp.queryInterface (unotmp); + if (xls.changed == 2) + # Some trickery as Octave Java cannot create non-numeric arrays + lProps = javaArray ('com.sun.star.beans.PropertyValue', 1); + lProp = java_new ('com.sun.star.beans.PropertyValue', "Overwrite", 0, true, []); + lProps(1) = lProp; + # OK, store file + xStore.storeAsURL (xls.filename, lProps); + else + xStore.store (); + endif + endif + endif + xls.changed = -1; # Needed for check on properly shutting down OOo + # Workaround: + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XModel'); + xModel = xls.app.xComp.queryInterface (unotmp); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.util.XCloseable'); + xClosbl = xModel.queryInterface (unotmp); + xClosbl.close (true); + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XDesktop'); + xDesk = xls.app.aLoader.queryInterface (unotmp); + xDesk.terminate(); + xls.changed = 0; + catch + if (force) + # Force closing OOo + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.frame.XDesktop'); + xDesk = xls.app.aLoader.queryInterface (unotmp); + xDesk.terminate(); + else + warning ("Error closing xls pointer (UNO)"); + endif + return + end_try_catch + +# elseif + + endif + + if (xls.changed && xls.changed < 3) + warning (sprintf ("File %s could not be saved. Read-only or in use elsewhere?\nFile pointer preserved.", xls.filename)); + if (force) + xls = []; + endif + else + xls = []; + endif + +endfunction