Update httemplate/elements/selectlayers.html
[freeside.git] / httemplate / search / report_tax-xls.cgi
1 <% $data %>
2 <%init>
3 my $htmldoc = include('report_tax.cgi');
4
5 my ($title) = ($htmldoc =~ /<title>\s*(.*)\s*<\/title>/i);
6
7 # do this first so we can override the format if it's too many rows
8 # attribs option: how to locate the table?  It's the only one with class="grid".
9 my $te = HTML::TableExtract->new(attribs => {class => 'grid'});
10 $te->parse($htmldoc);
11 my $table = $te->first_table_found;
12
13 my $override = ($table->row_count >= 65536 ? 'XLSX' : '');
14 my $format = $FS::CurrentUser::CurrentUser->spreadsheet_format($override);
15 my $filename = 'report_tax'.$format->{extension};
16
17 http_header('Content-Type' => $format->{mime_type});
18 http_header('Content-Disposition' => qq!attachment;filename="$filename"! );
19
20 my $data = '';
21 my $XLS = new IO::Scalar \$data;
22 my $workbook = $format->{class}->new($XLS)
23   or die "Error opening .xls file: $!";
24
25 # hardcoded formats, this could be handled better
26 my $light_gray = $workbook->set_custom_color(63, '#eeeeee');
27 my %format = (
28   title => {
29     size      => 24,
30     align     => 'center',
31     bg_color  => 'silver',
32   },
33   colhead => {
34     size      => 11,
35     bold      => 1,
36     align     => 'center',
37     valign    => 'vcenter',
38     text_wrap => 1,
39   },
40   rowhead => {
41     size      => 11,
42     valign    => 'bottom',
43     text_wrap => 1,
44   },
45   amount  => {
46     size      => 11,
47     align     => 'right',
48     valign    => 'bottom',
49     num_format=> 8,
50   },
51   'size-1' => {
52     size      => 7.5,
53     align     => 'center',
54     valign    => 'vcenter',
55     bold      => 1,
56     text_wrap => 1,
57   },
58   'size+1' => {
59     size      => 12,
60     align     => 'center',
61     valign    => 'vcenter',
62     bold      => 1,
63   },
64   text => {
65     size      => 11,
66     text_wrap => 1,
67   },
68 );
69 my %default = (
70   font      => 'Calibri',
71   bg_color  => $light_gray,
72   border    => 1,
73 );
74 my @widths = ( #ick
75   18, (10.5, 3) x 6, 10.5, 10.5, 3, 10.5, 3, 10.5, 3, 10.5
76 );
77 foreach (keys(%format)) {
78   my %f = (%default, %{$format{$_}});
79   $format{$_} = $workbook->add_format(%f);
80   $format{"m_$_"} = $workbook->add_format(%f); # for merged cells
81   $format{"t_$_"} = $workbook->add_format(%f, bg_color => 'yellow'); # totals
82 }
83 my $ws = $workbook->add_worksheet('taxreport');
84
85 my @sheet;
86 $sheet[0][0] = {
87   text    => $title,
88   format  => 'title',
89   colspan => '18',
90 };  
91 # excel position
92 my $x = 0;
93 my $y = 3;
94 foreach my $row ($table->rows()) {
95   $x = 0;
96   $sheet[$y] = [];
97   foreach my $cell (@$row) {
98     if ($cell and ref($cell) eq 'HTML::ElementTable::DataElement') {
99       my $f = 'text';
100       if ( $cell->as_HTML =~ /font/i ) {
101         my ($el) = $cell->content_list;
102         $f = 'size'.$el->attr('size') if $el->attr('size');
103       }
104       elsif ( $cell->as_text =~ /^\$/ ) {
105         $f = 'amount'
106       }
107       elsif ( $cell->tag eq 'th' ) {
108         $f = 'colhead';
109       }
110       elsif ( $x == 0 ) {
111         $f = 'rowhead';
112       }
113       $sheet[$y][$x] = {
114         text    => $cell->as_text,
115         format  => $f,
116         rowspan => $cell->attr('rowspan'),
117         colspan => $cell->attr('colspan'),
118       };
119     }
120     $x++;
121   } #for $cell
122   $y++;
123 }
124
125 $y = 0;
126 foreach my $row (@sheet) {
127   $x = 0;
128   my $t_row = 1 if($row->[0]->{'text'} eq 'Total');
129   foreach my $cell (@$row) {
130     if ($cell) {
131       my $f = $cell->{format};
132       if ($cell->{rowspan} > 1 or $cell->{colspan} > 1) {
133         my $range = xl_range_formula(
134           'Taxreport', 
135           $y,
136           $y - 1 + ($cell->{rowspan} || 1),
137           $x,
138           $x - 1 + ($cell->{colspan} || 1)
139         );
140         $ws->merge_range($range, $cell->{text}, $format{"m_$f"});
141       }
142       else {
143         $f = "t_$f" if $t_row;
144         $ws->write($y, $x, $cell->{text}, $format{$f});
145       }
146     } #if $cell
147     $x++;
148   }
149   $y++;
150 }
151
152 for my $x (0..scalar(@widths)-1) {
153   $ws->set_column($x, $x, $widths[$x]);
154 }
155
156 $workbook->close;
157
158 </%init>