Answer the question
In order to leave comments, you need to log in
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
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.
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 questionAsk a Question
731 491 924 answers to any question