From: <prn...@us...> - 2011-05-15 20:36:58
|
Revision: 8263 http://octave.svn.sourceforge.net/octave/?rev=8263&view=rev Author: prnienhuis Date: 2011-05-15 20:36:51 +0000 (Sun, 15 May 2011) Log Message: ----------- Experimental UNO support added Modified Paths: -------------- trunk/octave-forge/main/io/inst/oct2ods.m trunk/octave-forge/main/io/inst/spsh_chkrange.m Modified: trunk/octave-forge/main/io/inst/oct2ods.m =================================================================== --- trunk/octave-forge/main/io/inst/oct2ods.m 2011-05-15 20:36:29 UTC (rev 8262) +++ trunk/octave-forge/main/io/inst/oct2ods.m 2011-05-15 20:36:51 UTC (rev 8263) @@ -1,4 +1,4 @@ -## Copyright (C) 2009,2010 Philip Nienhuis <pr.nienhuis at users.sf.net> +## Copyright (C) 2009,2010,2011 Philip Nienhuis <pr.nienhuis 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 @@ -108,6 +108,8 @@ ## 2010-11-12 Better input argument checks ## 2010-11-13 Reset ods.limits when read was successful ## 2010-11-13 Added check for 2-D input array +## 2011-03-23 First try of odfdom 0.8.7 +## 2011-05-15 Experimental UNO support added ## ## Last update of subfunctions below: 2012-12-08 @@ -158,16 +160,23 @@ switch ods.odfvsn case "0.7.5" [ ods, rstatus ] = oct2jotk2ods (c_arr, ods, wsh, crange, spsh_opts); - case "0.8.6" + case {"0.8.6", "0.8.7"} [ ods, rstatus ] = oct3jotk2ods (c_arr, ods, wsh, crange, spsh_opts); otherwise error ("Unsupported odfdom version"); endswitch + elseif (strcmp (ods.xtype, 'JOD')) # Write ods file tru Java & jOpenDocument. API still leaves lots to be wished... [ ods, rstatus ] = oct2jod2ods (c_arr, ods, wsh, crange); + + elseif (strcmp (ods.xtype, 'UNO')) + # Write ods file tru Java & UNO bridge (OpenOffice.org & clones) + [ ods, rstatus ] = oct2uno2ods (c_arr, ods, wsh, crange, spsh_opts); + # elseif # ---- < Other interfaces here > + else error (sprintf ("ods2oct: unknown OpenOffice.org .ods interface - %s.", ods.xtype)); endif @@ -657,7 +666,8 @@ ## 2010-08-22 odfdom 0.8.6 is there... seems to work with just one bug, easily worked around ## 2010-10-27 Improved file change tracking tru ods.changed ## 2010-11-12 Improved file change tracking tru ods.changed -#3 2010-12-08 Bugfixes (obj -> arg L.715; removed stray arg in call to spsh_prstype L.719) +## 2010-12-08 Bugfixes (obj -> arg L.715; removed stray arg in call to spsh_prstype L.719) +## 2011-03-23 First try of odfdom 0.8.7 function [ ods, rstatus ] = oct3jotk2ods (c_arr, ods, wsh, crange, spsh_opts) @@ -674,7 +684,11 @@ # makes physical copies only when needed (?) odfroot = odfcont.getRootElement (); offsprdsh = ods.app.getContentRoot(); - spsh = odfcont.getOdfDocument (); + if (strcmp (ods.odfvsn, '0.8.7')) + spsh = odfcont.getDocument (); + else + spsh = odfcont.getOdfDocument (); + endif # Get some basic spreadsheet data from the pointer using ODFtoolkit autostyles = odfcont.getOrCreateAutomaticStyles(); @@ -970,3 +984,138 @@ endif endfunction + + +## Copyright (C) 2011 Philip Nienhuis <prn...@us...> +## +## 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/>. + +## oct2uno2ods - transfer data to ods or xls file using Java/UNO bridge +## with OpenOffice_org & clones + +## Author: Philip Nienhuis <prn...@us...> +## Created: 2011-05-15 + +function [ ods, rstatus ] = oct2uno2ods (c_arr, ods, wsh, crange, spsh_opts) + + changed = 0; + newsh = 0; + ctype = [1, 2, 3, 4, 5]; # Float, Logical, String, Formula, Empty + + # Get handle to sheet, create a new one if needed + sheets = ods.workbook.getSheets (); + sh_names = sheets.getElementNames (); + # Check sheet pointer + # FIXME sheet capacity check needed + if (isnumeric (wsh)) + if (wsh < 1) + error ("Illegal sheet index: %d", wsh); + elseif (wsh > numel (sh_names)) + # New sheet to be added. First create sheet name but check if it already exists + shname = sprintf ("Sheet%d", numel (sh_names) + 1); + jj = strmatch (wsh, {sh_names}); + if (~isempty (jj)) + # New sheet name already in file, try to create a unique & reasonable one + ii = 1; filler = ''; maxtry = 5; + while (ii <= maxtry) + shname = sprintf ("Sheet%s%d", [filler "_"], numel (sh_names + 1)); + if (isempty (strmatch (wsh, {sh_names}))) + ii = 10; + else + ++ii; + endif + endwhile + if (ii > maxtry + 1) + error ("Could not add sheet with a unique name to file %s"); + endif + endif + wsh = shname; + newsh = 1; + else + # turn wsh index into the associated sheet name + wsh = sh_names (wsh); + endif + else + # wsh is a sheet name. See if it exists already + if (isempty (strmatch (wsh, {sh_names}))) + # Not found. New sheet to be added + newsh = 1; + endif + endif + if (newsh) + # Add a new sheet. Sheet index MUST be a Java Short object + shptr = java_new ("java.lang.Short", sprintf ("%d", numel (sh_names) + 1)); + sh = sheets.insertNewByName (wsh, shptr); + sheets = ods.workbook.getSheets (); + sh_names = sheets.getElementNames (); + endif + # At this point we have a valid sheet name. Use it to get a sheet handle + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.sheet.XSpreadsheet'); + sh = sheets.getByName (wsh).getObject.queryInterface (unotmp); + + # Check size of data array & range / capacity of worksheet & prepare vars + [nr, nc] = size (c_arr); + [topleft, nrows, ncols, trow, lcol] = spsh_chkrange (crange, nr, nc, ods.xtype, ods.filename); + --trow; --lcol; # Zero-based row # & col # + if (nrows < nr || ncols < nc) + warning ("Array truncated to fit in range"); + c_arr = c_arr(1:nrows, 1:ncols); + endif + + # Parse data array, setup typarr and throw out NaNs to speed up writing; + typearr = spsh_prstype (c_arr, nrows, ncols, ctype, spsh_opts, 0); + if ~(spsh_opts.formulas_as_text) + # Find formulas (designated by a string starting with "=" and ending in ")") + fptr = cellfun (@(x) ischar (x) && strncmp (x, "=", 1), c_arr); + typearr(fptr) = ctype(4); # FORMULA + endif + + # Transfer data to sheet + for ii=1:nrows + for jj=1:ncols + try + XCell = sh.getCellByPosition (lcol+jj-1, trow+ii-1); + switch typearr(ii, jj) + case 1 # Float + XCell.setValue (c_arr{ii, jj}); + case 2 # Logical. Convert to float + XCell.setValue (double (c_arr{ii, jj})); + case 3 # String + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.text.XText'); + XCell.queryInterface (unotmp).setString (c_arr{ii, jj}); + case 4 # Formula + if (spsh_opts.formulas_as_text) + unotmp = java_new ('com.sun.star.uno.Type', 'com.sun.star.text.XText'); + XCell.queryInterface (unotmp).setString (c_arr{ii, jj}); + else + XCell.setFormula (c_arr{ii, jj}); + endif + otherwise + # Empty cell + endswitch + changed = 1; + catch + printf ("Error writing cell %s (typearr() = %d)\n", calccelladdress(trow+ii, lcol+jj), typearr(ii, jj)); + keyboard + end_try_catch + endfor + endfor + + if (changed) + ods.changed = max (min (ods.changed, 2), changed); # Preserve 2 (new file), 1 (existing) + rstatus = 1; + endif + +endfunction Modified: trunk/octave-forge/main/io/inst/spsh_chkrange.m =================================================================== --- trunk/octave-forge/main/io/inst/spsh_chkrange.m 2011-05-15 20:36:29 UTC (rev 8262) +++ trunk/octave-forge/main/io/inst/spsh_chkrange.m 2011-05-15 20:36:51 UTC (rev 8263) @@ -1,4 +1,4 @@ -## Copyright (C) 2010 Philip Nienhuis +## Copyright (C) 2010,2011 Philip Nienhuis <prn...@us...> ## ## 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 @@ -28,14 +28,13 @@ ## ## @end deftypefn -## Author: Philip Nienhuis, <prn...@us...> +## Author: Philip Nienhuis <prn...@us...> ## Created: 2010-08-02 ## Updates: ## 2010-08-25 Option for supplying file pointer rather than interface_type & filename ## (but this can be wasteful if the file ptr is copied) ## 2011-03-29 Bug fix - unrecognized pointer struct & wrong type error msg -## 2011-04-21 Bug fix - wouldn't properly detect OOXML from extension -## '' Added tests +## 2011-05-15 Experimental UNO support added (OpenOffice.org & clones) function [ topleft, nrows, ncols, trow, lcol ] = spsh_chkrange (crange, nr, nc, intf, filename=[]) @@ -54,20 +53,24 @@ # Define max row & column capacity from interface type & file suffix switch xtype - case {'COM', 'POI'} - if (strcmp ('xls', tolower (filename(end-2:end)))) + case { 'COM', 'POI' } + if (strmatch (tolower (filename(end-3:end)), '.xls')) # BIFF5 & BIFF8 ROW_CAP = 65536; COL_CAP = 256; else # OOXML (COM needs Excel 2007+ for this) ROW_CAP = 1048576; COL_CAP = 16384; endif - case {'JXL', 'OXS'} + case { 'JXL', 'OXS' } # JExcelAPI & OpenXLS can only process BIFF5 & BIFF8 ROW_CAP = 65536; COL_CAP = 256; - case {'OTK', 'JOD'} + case { 'OTK', 'JOD' } # ODS ROW_CAP = 65536; COL_CAP = 1024; + case { 'UNO' } + # ODS; LibreOffice has a higher row capacity + # FIXME - use UNO calls to check physical row capacity + ROW_CAP = 65536; COL_CAP = 1024; otherwise error (sprintf ("Unknown interface type - %s\n", xtype)); endswitch @@ -97,52 +100,3 @@ ncols = min (ncols, nc); endfunction - -# Test COM using ptr struct -%!test -%! intf = struct ("xtype", 'COM', "app", [], "filename", 'test.xls', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:IY67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 257, intf); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 253, 2, 4]); - -# Test COM using ptr struct -%!test -%! intf = struct ("xtype", 'COM', "app", [], "filename", 'test.xls', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:IY67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 257, 'COM', 'filename.xls'); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 253, 2, 4]); - -# Test POI using ptr struct -%!test -%! intf = struct ("xtype", 'POI', "app", [], "filename", 'test.xls', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:IY67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 257, intf); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 253, 2, 4]); - -# Test POI OOXML using ptr struct -%!test -%! intf = struct ("xtype", "POI", "app", [], "filename", 'test.xlsx', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D3:xfe1058888'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 1200000, 20000, intf); -%! assert ([a1, a2, a3, a4, a5], ['D3', 1048574, 16381, 3, 4]); - -# Test JXL using ptr struct -%!test -%! intf = struct ("xtype", "JXL", "app", [], "filename", 'test.xls', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:IY67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 257, intf); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 253, 2, 4]); - -# Test OTK using ptr struct -%!test -%! intf = struct ("xtype", 'OTK', "app", [], "filename", 'test.ods', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:AML67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 1200, intf); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 1021, 2, 4]); - -# Test JOD using ptr struct -%!test -%! intf = struct ("xtype", 'JOD', "app", [], "filename", 'test.ods', "workbook", [], "changed", 0, "limits", []); -%! tstrange = 'D2:AML67356'; -%! [a1, a2, a3, a4, a5] = spsh_chkrange (tstrange, 65536, 1200, intf); -%! assert ([a1, a2, a3, a4, a5], ['D2', 65535, 1021, 2, 4]); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |