--- loncom/interface/Attic/lonspreadsheet.pm 2002/11/05 15:00:27 1.133
+++ loncom/interface/Attic/lonspreadsheet.pm 2002/11/07 15:37:02 1.135
@@ -1,5 +1,5 @@
#
-# $Id: lonspreadsheet.pm,v 1.133 2002/11/05 15:00:27 matthew Exp $
+# $Id: lonspreadsheet.pm,v 1.135 2002/11/07 15:37:02 matthew Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -62,6 +62,8 @@ use GDBM_File;
use HTML::TokeParser;
use Apache::lonhtmlcommon;
use Apache::loncoursedata;
+use Apache::File();
+use Spreadsheet::WriteExcel;
#
# Caches for coursewide information
#
@@ -1107,9 +1109,8 @@ sub exportdata {
# ========================================================== End of Spreadsheet
# =============================================================================
-
#
-# Procedures for screen output
+# Procedures for spreadsheet output
#
# --------------------------------------------- Produce output row n from sheet
@@ -1143,9 +1144,15 @@ sub sort_indicies {
return @sortidx;
}
-########################################################################
-########################################################################
-
+#############################################################
+### ###
+### Spreadsheet Output Routines ###
+### ###
+#############################################################
+
+############################################
+## HTML output routines ##
+############################################
sub html_editable_cell {
my ($cell,$bgcolor) = @_;
my $result;
@@ -1177,9 +1184,6 @@ sub html_uneditable_cell {
return ' '.$value.' ';
}
-########################################################################
-########################################################################
-
sub outsheet_html {
my ($sheet,$r) = @_;
my ($num_uneditable,$realm,$row_type);
@@ -1349,6 +1353,9 @@ END
return 1;
}
+############################################
+## csv output routines ##
+############################################
sub outsheet_csv {
my ($sheet,$r) = @_;
my $csvdata = '';
@@ -1370,26 +1377,183 @@ sub outsheet_csv {
@Values = ();
}
#
- $r->print('
'.$csvdata."\n
");
+ # Write the CSV data to a file and serve up a link
+ #
+ my $filename = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.csv';
+ my $file;
+ unless ($file = Apache::File->new('>'.'/home/httpd'.$filename)) {
+ $r->log_error("Couldn't open $filename for output $!");
+ $r->print("Problems occured in writing the csv file. ".
+ "This error has been logged. ".
+ "Please alert your LON-CAPA administrator.");
+ $r->print("
'.
+ 'Your CSV spreadsheet.'."\n");
+ #
+ return 1;
+}
+
+############################################
+## Excel output routines ##
+############################################
+sub outsheet_recursive_excel {
+ my ($sheet,$r) = @_;
+ return undef if ($sheet->{'sheettype'} ne 'classcalc');
+ my ($workbook,$filename) = &create_excel_spreadsheet($sheet,$r);
+ return undef if (! defined($workbook));
+ #
+ # Create main worksheet
+ my $main_worksheet = $workbook->addworksheet('main');
+ #
+ # Figure out who the students are
+ my %f=&getformulas($sheet);
+ my $count = 0;
+ $r->print(" \n");
+ $r->rflush();
+ foreach (keys(%f)) {
+ next if ($_!~/^A(\d+)/ || $1 == 0 || ($f{$_}=~/^[!~-]/));
+ $count++;
+ my ($sname,$sdom) = split(':',$f{$_});
+ my $student_excel_worksheet=$workbook->addworksheet($sname.'@'.$sdom);
+ # Create a new spreadsheet
+ my $studentsheet = &makenewsheet($sname,$sdom,'studentcalc',undef);
+ # Read in the spreadsheet definition
+ &readsheet($studentsheet,'default_studentcalc');
+ # Determine the structure (contained assessments, etc) of the sheet
+ &updatesheet($studentsheet);
+ # Load in the (possibly cached) data from the assessment sheets
+ &loadrows($studentsheet);
+ # Compute the sheet
+ &calcsheet($studentsheet);
+ &Apache::lonnet::logthis("Sheet value for A0 = ".$sheet->{'values'}->{'A0'});
+ # Stuff the sheet into excel
+ &export_sheet_as_excel($studentsheet,$student_excel_worksheet);
+ if ($count % 5 == 0) {
+ $r->print($count.' students completed ');
+ $r->rflush();
+ }
+ }
+ #
+ $r->print('All students spreadsheets completed ');
+ $r->rflush();
+ #
+ # &export_sheet_as_excel fills $worksheet with the data from $sheet
+ &export_sheet_as_excel($sheet,$main_worksheet);
#
+ $workbook->close();
+ # Okay, the spreadsheet is taken care of, so give the user a link.
+ $r->print('
'.
+ 'Your Excel spreadsheet.'."\n");
return 1;
}
sub outsheet_excel {
my ($sheet,$r) = @_;
+ my ($workbook,$filename) = &create_excel_spreadsheet($sheet,$r);
+ return undef if (! defined($workbook));
+ my $sheetname;
+ if ($sheet->{'sheettype'} eq 'classcalc') {
+ $sheetname = 'Main';
+ } elsif ($sheet->{'sheettype'} eq 'studentcalc') {
+ $sheetname = $sheet->{'uname'}.'@'.$sheet->{'udom'};
+ } elsif ($sheet->{'sheettype'} eq 'assesscalc') {
+ $sheetname = $sheet->{'uname'}.'@'.$sheet->{'udom'}.' assessment';
+ }
+ my $worksheet = $workbook->addworksheet($sheetname);
+ #
+ # &export_sheet_as_excel fills $worksheet with the data from $sheet
+ &export_sheet_as_excel($sheet,$worksheet);
+ #
+ $workbook->close();
+ # Okay, the spreadsheet is taken care of, so give the user a link.
+ $r->print('
'.
+ 'Your Excel spreadsheet.'."\n");
+ return 1;
+}
+
+sub create_excel_spreadsheet {
+ my ($sheet,$r) = @_;
+ my $filename = '/prtspool/'.
+ $ENV{'user.name'}.'_'.$ENV{'user.domain'}.'_'.
+ time.'_'.rand(1000000000).'.xls';
+ #&Apache::lonnet::logthis("spreadsheet:filename = ".$filename);
+ my $workbook = Spreadsheet::WriteExcel->new('/home/httpd'.$filename);
+ if (! defined($workbook)) {
+ $r->log_error("Error creating excel spreadsheet $filename: $!");
+ $r->print("Problems creating new Excel file. ".
+ "This error has been logged. ".
+ "Please alert your LON-CAPA administrator");
+ return undef;
+ }
+ #
+ # The spreadsheet stores temporary data in files, then put them
+ # together. If needed we should be able to disable this (memory only).
+ # The temporary directory must be specified before calling 'addworksheet'.
+ # File::Temp is used to determine the temporary directory.
+ $workbook->set_tempdir('/home/httpd/perl/tmp');
+ #
+ # Determine the name to give the worksheet
+ return ($workbook,$filename);
}
+sub export_sheet_as_excel {
+ my $sheet = shift;
+ my $worksheet = shift;
+ ####################################
+ # Prepare to output rows
+ ####################################
+ my @Rows = &sort_indicies($sheet);
+ #
+ # Loop through the rows and output them one at a time
+ my $rows_output=0;
+ foreach my $rownum (@Rows) {
+ my ($rowlabel,@rowdata) = &get_row($sheet,$rownum);
+ my $cols_output = 0;
+ my $label = &format_excel_rowlabel($rowlabel);
+ $worksheet->write($rows_output,$cols_output++,$label);
+ if (ref($label)) {
+ $cols_output = (scalar(@$label));
+ }
+ foreach my $cell (@rowdata) {
+ $worksheet->write($rows_output,$cols_output++,
+ $cell->{'value'});
+ }
+ $rows_output++;
+ }
+ return;
+}
+
+############################################
+## XML output routines ##
+############################################
sub outsheet_xml {
my ($sheet,$r) = @_;
+ ## Someday XML
+ ## Will be rendered for the user
+ ## But not on this day
}
+##
+## Outsheet - calls other outsheet_* functions
+##
sub outsheet {
my ($r,$sheet)=@_;
- if (exists($ENV{'form.showcsv'})) {
+ if (! exists($ENV{'form.output'})) {
+ $ENV{'form.output'} = 'HTML';
+ }
+ if (lc($ENV{'form.output'}) eq 'csv') {
&outsheet_csv($sheet,$r);
-# } elsif (exists($ENV{'form.excel'})) {
-# &outsheet_excel($sheet,$r);
-# } elsif (exists($ENV{'form.xml'})) {
+ } elsif (lc($ENV{'form.output'}) eq 'excel') {
+ &outsheet_excel($sheet,$r);
+ } elsif (lc($ENV{'form.output'}) eq 'recursive excel') {
+ &outsheet_recursive_excel($sheet,$r);
+# } elsif (lc($ENV{'form.output'}) eq 'xml' ) {
# &outsheet_xml($sheet,$r);
} else {
&outsheet_html($sheet,$r);
@@ -1533,6 +1697,8 @@ sub makenewsheet {
$sheet->{'cnum'} = $ENV{'course.'.$ENV{'request.course.id'}.'.num'};
$sheet->{'cdom'} = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
$sheet->{'chome'} = $ENV{'course.'.$ENV{'request.course.id'}.'.home'};
+ $sheet->{'coursedesc'} = $ENV{'course.'.$ENV{'request.course.id'}.
+ 'description'};
$sheet->{'uhome'} = &Apache::lonnet::homeserver($uname,$udom);
#
#
@@ -1776,7 +1942,7 @@ sub format_csv_rowlabel {
return '"'.$result.'"';
}
-sub format_plain_rowlabel {
+sub format_excel_rowlabel {
my $rowlabel = shift;
return '' if ($rowlabel eq '');
my ($type,$labeldata) = split(':',$rowlabel,2);
@@ -1787,8 +1953,10 @@ sub format_plain_rowlabel {
$result = $title;
} elsif ($type eq 'student') {
my ($sname,$sdom,$fullname,$section,$id) = split(':',$labeldata);
- $result = '"'.
- join('","',($sname,$sdom,$fullname,$section,$id).'"');
+ $section = '' if (! defined($section));
+ $id = '' if (! defined($id));
+ my @Data = ($sname,$sdom,$fullname,$section,$id);
+ $result = \@Data;
} elsif ($type eq 'parameter') {
$labeldata =~ s/ / /g;
$result = $labeldata;
@@ -1992,7 +2160,7 @@ sub updatestudentassesssheet {
# ------------------------------------------------ Load data for one assessment
-sub loadstudent {
+sub loadstudent{
my ($sheet)=@_;
my %c=();
my %f=&getformulas($sheet);
@@ -2044,8 +2212,10 @@ sub loadstudent {
#
sub loadcourse {
my ($sheet,$r)=@_;
+ #
my %c=();
my %f=&getformulas($sheet);
+ #
my $total=0;
foreach (keys(%f)) {
if ($_=~/^A(\d+)/) {
@@ -2368,7 +2538,7 @@ sub exportsheet {
}
#
# Not cached
- #
+ #
my ($newsheet)=&makenewsheet($uname,$udom,$stype,$usymb);
&readsheet($newsheet,$fn);
&updatesheet($newsheet);
@@ -2497,9 +2667,16 @@ sub cachedssheets {
sub handler {
my $r=shift;
+ my ($sheettype) = ($r->uri=~/\/(\w+)$/);
+
if (! exists($ENV{'form.Status'})) {
$ENV{'form.Status'} = 'Active';
}
+ if ( ! exists($ENV{'form.output'}) ||
+ ($sheettype ne 'classcalc' &&
+ lc($ENV{'form.output'}) eq 'recursive excel')) {
+ $ENV{'form.output'} = 'HTML';
+ }
# Check this server
my $loaderror=&Apache::lonnet::overloaderror($r);
if ($loaderror) { return $loaderror; }
@@ -2603,8 +2780,7 @@ ENDSCRIPT
undef %updatedata;
}
# Read new sheet or modified worksheet
- $r->uri=~/\/(\w+)$/;
- my ($sheet)=&makenewsheet($aname,$adom,$1,$ENV{'form.usymb'});
+ my ($sheet)=&makenewsheet($aname,$adom,$sheettype,$ENV{'form.usymb'});
#
# If a new formula had been entered, go from work copy
if ($ENV{'form.unewfield'}) {
@@ -2753,10 +2929,24 @@ ENDSCRIPT
$r->print('>');
#
# CSV format checkbox (classcalc sheets only)
- $r->print(' Output CSV format: print(' checked') if ($ENV{'form.showcsv'});
- $r->print('>');
+ $r->print(' Output as \n");
+ #
if ($sheet->{'sheettype'} eq 'classcalc') {
$r->print(' Student Status: '.
&Apache::lonhtmlcommon::StatusOptions
@@ -2764,13 +2954,13 @@ ENDSCRIPT
}
#
# Buttons to insert rows
- $r->print(<
-
-
-ENDINSERTBUTTONS
+# $r->print(<
+#
+#
+#ENDINSERTBUTTONS
# Print out sheet
&outsheet($r,$sheet);
$r->print('