A
A
artem782014-09-15 13:27:48
Perl
artem78, 2014-09-15 13:27:48

Why does text disappear when merging Excel files in Perl?

I am writing a small program in Perl to merge xlsx files. I open the merged file and see that the text has disappeared, only numbers remain. Perhaps the matter is in the wrong encoding, but I can not understand from which to which I need to translate.

sub processButton_Click {
  my $target_file_name = Win32::GUI::GetSaveFileName(
    -title  => 'Сохранить файл',
        -filter => ["Excel (*.xslx)" => "*.xlsx"]
  );
  return unless $target_file_name;
  
  
  $mainWindow->statusLabel->Text('');
  $mainWindow->addButton->Enable(0);
  $mainWindow->removeButton->Enable(0);
  $mainWindow->processButton->Enable(0);
  my $target_workbook = Excel::Writer::XLSX->new("$target_file_name.xlsx");
  my $warns = '';
  my $converter = Text::Iconv->new("utf-8", "windows-1251");
  
  my @source_files = ();
  my $n = $mainWindow->fileList->GetCount();
  foreach my $idx (0 .. $n-1) {
    push(@source_files, $mainWindow->fileList->GetText($idx));
  }

  
  my $thread = threads->create(sub {
    foreach my $i (keys @source_files) {
      $mainWindow->statusLabel->Text("Обработка " . ($i + 1) . " из $n ...");
      my $source_file = $source_files[$i];
      my $reader = Excel::Reader::XLSX->new();
      my $source_workbook = $reader->read_file($source_file);
      if (!defined $source_workbook) {
        $warns .= "Невозможно прочитать $source_file\n";
        next;
      }
      
      $source_file =~ m/^.*(?:\\|\/)(.*?).[a-zA-Z0-9]+$/;
      my $target_worksheet_name = decode('windows-1251', $1);
      my $target_worksheet = $target_workbook->add_worksheet($target_worksheet_name);
      
      my ($source_worksheet) = $source_workbook->worksheets();
     
      while (my $row = $source_worksheet->next_row()) {
        while (my $cell = $row->next_cell()) {
          my $value = $cell->value();
          $target_worksheet->write($cell->row(), $cell->col(), $value);
        }
      }
    }
    
    $mainWindow->statusLabel->Text('Выполнено');
    $mainWindow->addButton->Enable(1);
    $mainWindow->removeButton->Enable(1);
    $mainWindow->processButton->Enable(1);
    Win32::GUI::MessageBox(0, $warns, '', MB_ICONWARNING()) if $warns;
    
    $target_workbook->close();
  });

}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
noize, 2014-09-16
@noize

1. Don't use threads, they are deprecated. If you need to process in several threads, do it better through fork
2. Stick print/say everywhere, for example, after the line
$source_file =~ m/^.*(?:\\|\/)(.*?).[a- zA-Z0-9]+$/;
put print $1 . "\n"; to make sure that the regular expression is correct, and so on in the code.

G
gangabass, 2014-10-23
@gangabass

Maybe it's Excel::Reader::XLSX . My code works:

use Excel::Writer::XLSX;
use Spreadsheet::ParseXLSX;
use threads;
use feature qw(say);
use Encode qw(decode);

my $target_workbook = Excel::Writer::XLSX->new("Result.xlsx");

#Обрабатываю два файла "Sample_Сентябрь_2014.xlsx" и "Sample_Октябрь_2014.xlsx")
my @source_files = glob("Sample_*.xlsx");


my $thread = threads->create(
    sub {
        foreach my $source_file (@source_files) {

            my $reader          = Spreadsheet::ParseXLSX->new();
            my $source_workbook = $reader->parse($source_file);

            my ($target_worksheet_name) = $source_file =~ m/Sample_(.+)\.xlsx$/;

            $target_worksheet_name =
              decode( 'windows-1251', $target_worksheet_name );
            my $target_worksheet =
              $target_workbook->add_worksheet($target_worksheet_name);

            my ($worksheet) = $source_workbook->worksheets();

            my ( $row_min, $row_max ) = $worksheet->row_range();
            my ( $col_min, $col_max ) = $worksheet->col_range();

            foreach my $row ( $row_min .. $row_max ) {

                foreach my $col ( $col_min .. $col_max ) {

                    my $cell = $worksheet->get_cell( $row, $col );
                    my $value = $cell->value();
                    $target_worksheet->write( $row, $col, $value );
                }
            }
        }

        $target_workbook->close();
        exit;
    }
);

$thread->join();

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question