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

标签 mysql jsp jsp-tags taglib

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

MySQL 按 adding extra rows 进行小计到组字段设置为 NULL 的结果集。

有更好的选择吗?打印表格很重要,分页和排序会很好,但没有它们我也可以生活。不得进行任何形式的编辑。

最佳答案

我写了自己的快速而肮脏的标签。请注意,它需要 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>

column标签作用不大,只是将列定义添加到table标签中以供以后使用。

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);
    }
}

关于mysql - 用于显示带有分组和小计的 MySQL 汇总查询的 JSP 标记库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31320034/

相关文章:

java - <c :redirect url =""> is used in jsp 时如何设置 url prams

java - Fortify 报告 "Privacy violation"问题

mysql - 跟踪用户事件日志 - SQL 与 NoSQL?

python - SQLObject 抛出 : Unknown database 'dbname?charset=utf8'

java - 从 struts2 应用程序中的 jsp 重定向

java - 在 JSP 或 JVM 中设置区域设置无法正确格式化数字

javascript - 我需要传递 a 期望的参数。标记文件,使用 javascript

java - JSP获取html类型=数字输入字段的值

java - 在 LAN 客户端上测试 MySQL 数据库

c# - 获取MySql数据库中的blob文件