But then I found another problem. I wanted to freeze the headers row and the freeze_panes() method didn't seem to work as it worked with Spreadsheet::WriteExcel. I read again the documentation and found out to my dismay that it's not yet supported in the XML version (although it will eventually be implemented). I could try to implement it myself, but I don't know well enough this XML vocabulary and it would take me far more time than I can afford right now. So I created a poor man's freeze panes functionality --I always wanted to create a poor man's version of something (just for the sake of using that buzzword); actually, I have done it many times, but never on purpose. So, here is the procedure I followed: I froze panes manually on a sample report open in Excel, and saved it. Then I compared the new file and the original one to get the lines added, and modified my code to insert that patch in a second pass into every automatically generated report:
my $patch = <<'END';
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<Selected/>
<FreezePanes/>
<FrozenNoSplit/>
<SplitHorizontal>1</SplitHorizontal>
<TopRowBottomPane>1</TopRowBottomPane>
<ActivePane>2</ActivePane>
<Panes>
<Pane>
<Number>3</Number>
</Pane>
<Pane>
<Number>2</Number>
<ActiveRow>2</ActiveRow>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
<x:FreezePanes x:Range="A2"> </x:FreezePanes>
END
open my $in, '<:encoding(UTF-8)', $log_path;
my $text = do { local $/; <$in> };
close $in;
chop($patch);
$text =~ s/<\/Table>/<\/Table>\n$patch/;
open my $out, '>:encoding(UTF-8)', $log_path;
print $out $text;
close $out;
Yes, it's a dirty trick, but it works!



