【问题标题】:JSP tag library to display MySQL rollup query with grouping and subtotalsJSP 标记库,用于显示带有分组和小计的 MySQL 汇总查询
【发布时间】:2015-09-27 23:29:41
【问题描述】:

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

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

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

【问题讨论】:

    标签: mysql jsp jsp-tags taglib


    【解决方案1】:

    我写了我自己的快速而肮脏的标签。请注意,它需要 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标签的作用不大,只是将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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多