> On Oct 29, 2015, at 6:44 PM, Craig A. Berry <craigbe...@me.com> wrote:
> 
> 
> I got somewhat farther by setting this:
> 
> $ DEFINE DECC$FILENAME_UNIX_REPORT 1
> 
> and testing with [.examples]demo.pl, but the resulting file is corrupt. 

> Nothing looks greatly amiss in the VMS version except that the oddly named 
> file [Content_Types].xml is missing.  The file does exist in the temp 
> directory on VMS:
> 
> $ dir/size [...]^[Content_Types^].xml;1
> 
> Directory MDA0:[CRAIG.SCRATCH.bGENbxoyB2]
> 
> ^[Content_Types^].xml;1
>                           3
> 
> Total of 1 file, 3 blocks.
> 
> so something is preventing that file from getting added to the zip/xlsx 
> archive.  

And that something is the following line of code:

 my $wanted = sub { push @xlsx_files, $File::Find::name if -f };

The -f file test operator is a pretty thin wrapper around the CRTL stat 
function, which fails with [Content_Types].xml, presumably because, while it’s 
a valid Unix-format specification, it’s also a valid VMS-format directory and 
file specification.  There is no choice about what to name this file — it’s a 
standard part of an XLSX archive.  

If you give it a hint by prepending a little Unix syntax (“./“) or escape the 
brackets to make it unambiguously a VMS-syntax file, it’s ok, but on its own it 
is not recognized as a file.

$ perl -e "print -f './[Content_Types].xml' ? 'Y' : 'N';"
Y
$ perl -e "print -f '^[Content_Types^].xml' ? 'Y' : 'N';"
Y
$ perl -e "print -f '[Content_Types].xml' ? 'Y' : 'N’”
N

The solution is simple because what the code in question is doing is trying to 
exclude directories from its list of files to include in the archive and only 
include files.  So instead of saying “is it a file?” we can say “is it not a 
directory?”, like so:

$ gdiff -pu lib/Excel/Writer/XLSX/Workbook.pm;-0 
lib/Excel/Writer/XLSX/Workbook.pm
--- lib/Excel/Writer/XLSX/Workbook.pm;-0        2015-10-29 14:09:16 -0500
+++ lib/Excel/Writer/XLSX/Workbook.pm   2015-10-30 09:14:16 -0500
@@ -964,7 +964,7 @@ sub _store_workbook {
     # with File::Find and pass each one to addFile().
     my @xlsx_files;

-    my $wanted = sub { push @xlsx_files, $File::Find::name if -f };
+    my $wanted = sub { push @xlsx_files, $File::Find::name unless -d };

     File::Find::find(
         {
[end]

That in conjunction with DECC$FILENAME_UNIX_REPORT is all you need to get a 
valid XLSX file.  You can ignore my previous suggestion to convert the temp 
directory to Unix format as the DECC$ setting already does the equivalent.  In 
case it’s not obvious you also need an ODS-5 disk and a recentish version of 
Perl (I tested with 5.20.1).  

It still fails to clean up the temp directory and I think it’s that same 
[Content_Types].xml file that is causing the problem.  Don’t have a solution 
for that yet.
________________________________________
Craig A. Berry
mailto:craigbe...@mac.com

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser

Reply via email to