JSP标记库,用于显示具有分组和小计的MySQL汇总查询

时间:2015-07-09 14:10:23

标签: mysql jsp jsp-tags taglib

我需要使用来自MySQL GROUP BY a,b,c WITH ROLLUP查询的JSP将几个表显示为HTML。我正在寻找一个好的标签库来实现这一目标。我找到DisplayTag,但它最后一次更新是在2008年。我更喜欢使用MySQL计算的小计,这对于DisplayTag来说似乎很棘手。

MySQL通过adding extra rows对结果集进行小计,并将组字段设置为NULL。

有更好的选择吗?打印表很重要,分页和排序会很好,但我可以没有它们。没有任何编辑。

1 个答案:

答案 0 :(得分:0)

我写了自己的快速标签。请注意,它期望MySQL返回的汇总数据结构没有用其他任何东西进行测试。

用法示例:

<xxx:rollupTable cssClass="data" data="${data}">
    <xxx:rollupColumn title="Person" align="left" group="true" fieldName="personName" groupFieldName="personId" tooltipLink="person"/>
    <xxx:rollupColumn title="City" align="left" group="true" fieldName="cityName" groupFieldName="cityId" tooltipLink="city"/>
    <xxx:rollupColumn title="Price" align="right" format="#,##0.000" fieldName="price"/>
    <xxx:rollupColumn title="Amount" align="right" format="#,##0" fieldName="amount"/>
</xxx:rollupTable>

列标记不多,但将列定义添加到表标记以供以后使用。

package xxx.tags;

import...

public class RollupTableColumnTag extends SimpleTagSupport {
    private String title;
    private boolean group = false;
    private boolean sum = false;
    private String fieldName;       // field name to output
    private String groupFieldName;  // field name to test for rollup level changes
    private String align;
    private String format;
    private String tooltipLink;

    private DecimalFormat formatter;

    public void doTag() throws IOException, JspTagException {
        RollupTableTag parent = (RollupTableTag)findAncestorWithClass(this, RollupTableTag.class);
        if (parent == null) {
            throw new JspTagException("Parent tag not found.");
        }
        parent.addColumnDefinition(this);
    }

    public void setFormat(String format) {
        formatter = new DecimalFormat(format);
        this.format = format;
    }

    public DecimalFormat getFormatter() {
        return formatter;
    }
    // other getters and setters are standard, excluded
}

表标签可以完成实际的工作:

package xxx.tags;

import ...

public class RollupTableTag extends BodyTagSupport {
    protected String cssClass;
    protected List<Map> data;

    protected List<RollupTableColumnTag> columns;
    protected List<Integer> groups;

    public void setCssClass(String cssClass) {
        this.cssClass = cssClass;
    }

    public void setData(List data) {
        this.data = (List<Map>)data;
    }

    public int doStartTag() throws JspException {
        columns = new ArrayList<RollupTableColumnTag>();
        groups = new ArrayList<Integer>();
        return EVAL_BODY_BUFFERED;
    }

    public int doEndTag() throws JspException {
        try {
            JspWriter writer = pageContext.getOut();

            if (data.size() == 0) {
                writer.println("<P>No data.</P>");
                return EVAL_PAGE;
            }

            int nLevels = groups.size();
            int nNormalRowCount = 0;
            boolean[] bStartGroup = new boolean[nLevels];
            String[] sSummaryTitle = new String[nLevels];
            for (int i=0;i<nLevels;i++) {
                bStartGroup[i] = true;
            }

            writer.println("<TABLE class=\"" + cssClass + "\">");
            writer.println("<THEAD><TR>");
            for (RollupTableColumnTag column : columns) {
                writer.print("<TH");
                if (column.getAlign() != null) {
                    writer.print(" align=\"" + column.getAlign() + "\"");
                }
            writer.print(">" + column.getTitle() + "</TH>");
            }
            writer.println("</TR></THEAD>");
            writer.println("<TBODY>");
            for (Map dataRow : data) {
                StringBuffer out = new StringBuffer();
                out.append("<TR>");
                // grouping columns always come first
                String cellClass = null;
                for (int i=0;i<nLevels-1;i++) {
                    if (bStartGroup[i]) {
                        Object dataField = dataRow.get(columns.get(groups.get(i)).getFieldName());
                        sSummaryTitle[i] = dataField == null ? "" : dataField.toString();
                    }
                }

                int nLevelChanges = 0;
                for (int i=0;i<nLevels;i++) {
                    if (dataRow.get( columns.get(groups.get(i)).getGroupFieldName() ) == null) {
                        if (i>0) {
                            bStartGroup[i-1] = true;
                        }
                        nLevelChanges++;
                    } 
                }
                int nTotalLevel = nLevels - nLevelChanges;

                if (nLevelChanges == nLevels) {         // grand total row
                    cellClass = "grandtotal";
                    addCell(out, "Grand Total:", null, cellClass, nLevelChanges);
                } else if (nLevelChanges > 0) {         // other total row
                    boolean isOneLiner = (nNormalRowCount == 1);
                    nNormalRowCount = 0;
                    if (isOneLiner) continue;   // skip one-line sums
                    cellClass = "total"+nTotalLevel;
                    for (int i=0;i<nLevels-nLevelChanges-1;i++) {
                        addCell(out,"&nbsp;",null,cellClass, 1);
                    }
                    addCell(out, sSummaryTitle[nLevels-nLevelChanges-1] + " total:", null, cellClass, nLevelChanges+1);
                } else {                                // normal row
                    for (int i=0;i<nLevels;i++) {
                        if (bStartGroup[i]) {
                            RollupTableColumnTag column = columns.get(groups.get(i)); 
                            Object cellData = dataRow.get(column.getFieldName());
                            String displayVal = cellData != null ? cellData.toString() : "[n/a]";
                            if (column.getTooltipLink() != null && !column.getTooltipLink().isEmpty() && cellData != null) {
                                String tooltip = column.getTooltipLink();
                                int dataid = Integer.parseInt(dataRow.get(column.getGroupFieldName()).toString());
                                displayVal = "<div ajaxtooltip=\"" + tooltip + "\" ajaxtooltipid=\"" + dataid + "\">" + displayVal + "</div>";
                            }
                            addCell(out, displayVal, column.getAlign(), null, 1);
                        } else {
                            addCell(out,"&nbsp;", null, null, 1);
                        }
                    }
                    for (int i=0;i<nLevels-1;i++) {
                        bStartGroup[i] = false;
                    }
                    nNormalRowCount++;
                }
                // other columns
                for (RollupTableColumnTag column : columns) {
                    if (!column.isGroup()) {
                        Object content = dataRow.get(column.getFieldName());
                        String displayVal = "";
                        if (content != null) {
                            if (column.getFormat() != null) {
                                float val = Float.parseFloat(content.toString());
                                displayVal = column.getFormatter().format(val);
                            } else {
                                displayVal = content.toString();
                            }
                        }
                        addCell(out,displayVal,column.getAlign(),cellClass,1);
                    }
                }
                out.append("</TR>");
                // empty row for better readability
                if (groups.size() > 2 && nLevelChanges == groups.size() - 1) {
                    out.append("<TR><TD colspan=\"" + columns.size() + "\">&nbsp;</TD>");
                }
                writer.println(out);
            }
            writer.println("</TBODY>");
            writer.println("</TABLE>");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return EVAL_PAGE;
    }

    public void addCell(StringBuffer out, String content, String align, String cssClass, int colSpan) {
        out.append("<TD");
        if (align != null) {
            out.append(" align=\"" + align + "\"");
        }
        if (cssClass != null) {
            out.append(" class=\"" + cssClass + "\"");
        }
        if (colSpan > 1) {
            out.append(" colspan=\"" + colSpan + "\"");
        }
        out.append(">");
        out.append(content);
        out.append("</TD>");
    }

    public void addColumnDefinition(RollupTableColumnTag cd) {
        columns.add(cd);
        if (cd.isGroup()) groups.add(columns.size()-1);
    }
}