http://qs1969.pair.com?node_id=1226110


in reply to Spreadsheet::ParseXLSX filename non Latin Tk getOpenFile

Given what you're tried I assume you're familiar with the Unicode Bug. Others can provide better summaries of that than I can.

More generally, though, do the shortpaths themselves contain unicode characters or something that will be treated differently between Tk, perl and the OS?

Another option is to pass Spreadsheet::ParseXLSX::parse a file handle. It checks if the file argument is a file handle and acts accordingly, so if you can open the file using Win32::LongPath::openL then that will avoid the standard open call (assuming that is the cause of the error). https://github.com/doy/spreadsheet-parsexlsx/blob/master/lib/Spreadsheet/ParseXLSX.pm#L81.

Replies are listed 'Best First'.
Re^2: Spreadsheet::ParseXLSX filename non Latin Tk getOpenFile
by IB2017 (Pilgrim) on Nov 21, 2018 at 09:39 UTC

    I think the problem with shortpath is that the module - for me quite mysteriously - sometimes does provide a short path, sometime no. Moving around the same file (or directory structure), the module may start to provide the shortpath (otherwise it returns the original path). As far as I understood, this must depend on some quite wired Windows stuff. When a shortpath is provided, Spreadsheet::ParseXLSX works smoothly. However, it is unsatisfying if it doesn't work consistently.

    If my path is

    C:/Users/DE/Desktop/号召力打了/Ршзефф.xlsx

    The above code selects the path okay, and displays it fine in the UI (at least with the latest Tk). Passing this path to Spreadsheet::ParseXLSX does NOT work. Shouldn't Perl and Tk resolve this internally (no sure about the layer to the OS)? If a shortpath is returned

     C:\Users\FC\Desktop\7373~1\B030~1.XLS
    then is okay. If it is not return, I simply get again
    C:/Users/DE/Desktop/号召力打了/Ршзефф.xlsx
    which of course doesn't work.

    Can you elaborate more the idea to pass a file handle? Because, if the problem is not being able - in some circumstances - to get the shortpath, I guess I cannot have a filehandle too to pass, am I a wrong?

    I also tried to eliminate the Tk OpenFile and directly pass the path inside the script with:

    use utf8;
    my $workbook = $parser->parse('C:/Users/DE/Desktop/号召力打了/Ршзефф.xlsx');

    This doesn't work too.

      My thinking is that could could modify your code to something like (untested):

      # assumes $filename is set from Tk my $fh; Win32::LongPath::openL (\$fh, '<', $filename) or die "Unable to open $filename"; my $parser = Spreadsheet::ParseXLSX->new(); my $workbook = $parser->parse($fh); # do stuff

      openL is documented at https://metacpan.org/pod/Win32::LongPath#openL-FILEHANDLEREF,MODE,PATH

      You could also check the filename can be found using testL. https://metacpan.org/pod/Win32::LongPath#testL-TYPE,PATH

      This all comes with the caveat that I have not used these functions, although if it does work then it will help solve one of my own longstanding headaches with a Gtk2 application.

        Thank you for your idea. It works!?! Even for the path the module does not return a shortpath! How is this possible? I updated the script. It first tries to open it with the filehandle (on my test system it seems to work fine), it then tries to open it passing the shortpath. When no shortpath is returned by the module, the opration fails.

        use strict; use warnings; use Tk; use Win32::LongPath; use Spreadsheet::ParseXLSX; my $mw = Tk::MainWindow->new(); my $path; my $button = $mw->Button( -text => "Select a file", -command => \&show_file_dialog, )->pack(-side => 'left',); my $label = $mw->Entry( -text => 'No file yet', -width => 100, )->pack(-side => 'left',); $mw->MainLoop(); sub show_file_dialog { my @ext = ( ["Excel", ['xlsx']], ["All files", ['*']], ); $path = $mw->getOpenFile( -filetypes => \@ext, ); my $ShortPath = shortpathL ($path); $label->configure(-text => "$path - $ShortPath"); print "Trying to open file with Win32::LongPath::openL ... "; my $fh; Win32::LongPath::openL (\$fh, '<', $path) or die "Unable to open $path"; my $parser = Spreadsheet::ParseXLSX->new(); my $workbook = $parser->parse($fh); print "OK\n"; print "Trying to open file with shortpathL path ... "; my $parser = Spreadsheet::ParseXLSX->new(); my $workbook = $parser->parse($ShortPath); print "OK\n"; }