func SubjectSpreadsheet(e env.Env, f database.Filter, subj *subject.Subject, w io.Writer) error {

	file := xlsx.NewFile()

	g, err := e.GroupByFilteredClass(strconv.Itoa(subj.SubjID), "", f)
	if err != nil {
		return err
	}

	sheet, err := file.AddSheet("Progress Grid")
	if err != nil {
		return err
	}
	subjectGrid(sheet, g, subj, f.NatYear)

	sheet, err = file.AddSheet("Students")
	if err != nil {
		return err
	}
	subjectBroadsheet(e, subj, sheet, g)

	sheet, err = file.AddSheet("Export Details")
	if err != nil {
		return err
	}
	exportInfoSheet(sheet, e, f)

	file.Write(w)
	return nil
}
func subjectGroupPage(e env.Env, w http.ResponseWriter, r *http.Request) {

	if redir := checkRedirect(e, w, r, 2); redir {
		return
	}
	header(e, w, r, 2)
	defer footer(e, w, r)

	path := strings.Split(r.URL.Path, "/")
	subjID, err := strconv.Atoi(path[3])
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
		return
	}
	subj := e.Subjects[subjID]

	f := getFilter(e, r)
	g, err := e.GroupByFilteredClass(path[3], "", f)
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
	}

	classes, err := e.Classes(path[3], f.Date)
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
	}
	sort.Sort(sort.StringSlice(classes))

	clsGrps := []subGroup{}
	for _, c := range classes {
		grp := g.SubGroup(group.Class(subj.Subj, c))
		if len(grp.Students) > 0 {
			clsGrps = append(clsGrps, subGroup{c, template.URL(c), grp})
		}
	}

	data := struct {
		Query     template.URL
		Year      string
		Subj      *subject.Subject
		SubGroups []subGroup
		Matrix    subGroupMatrix
		Classes   []subGroup
	}{
		template.URL(r.URL.RawQuery),
		f.Year,
		subj,
		subGroups(g),
		groupMatrix(g),
		clsGrps,
	}

	err = e.Templates.ExecuteTemplate(w, "subjectgroups.tmpl", data)
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
		return
	}

}
// Performs analysis of the results
func progressGridPage(e env.Env, w http.ResponseWriter, r *http.Request) {

	if redir := checkRedirect(e, w, r, 2); redir {
		return
	}
	header(e, w, r, 2)
	defer footer(e, w, r)

	path := strings.Split(r.URL.Path, "/")
	subjID, err := strconv.Atoi(path[3])
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
		return
	}
	subject := e.Subjects[subjID]
	class := path[4]
	if strings.HasPrefix(path[4], "All") {
		class = ""
	}

	f := getFilter(e, r)
	g, err := e.GroupByFilteredClass(path[3], class, f)
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
	}

	data := struct {
		Query        template.URL
		Year         string
		Subject      string
		Level        string
		SubjID       string
		Class        string
		KS2Prior     string
		Group        group.Group
		ProgressGrid group.ProgressGrid
	}{
		template.URL(r.URL.RawQuery),
		f.Year,
		subject.Subj,
		subject.Lvl,
		path[3],
		path[4],
		subject.KS2Prior,
		g,
		g.ProgressGrid(subject, f.NatYear),
	}

	err = e.Templates.ExecuteTemplate(w, "progressgrid.tmpl", data)
	if err != nil {
		fmt.Fprintf(w, "Error: %v", err)
		return
	}

}