patternjavaMajor
Efficiently generating HTML CSS table using Java
Viewed 0 times
efficientlycssjavageneratingusinghtmltable
Problem
I am trying to generate an HTML table using Java. I have an object which I am iterating to make an HTML table.
Somehow, the code looks pretty ugly to me in the way HTML and CSS are being used within
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append("");
sb.append("");
sb.append("");
sb.append(" ClientName");
sb.append("");
sb.append(" SyncCount");
sb.append("");
sb.append(" SyncPercentile");
sb.append("");
sb.append(" SyncAvg");
sb.append("");
sb.append(" SyncMax");
sb.append("");
sb.append(" AsyncCount");
sb.append("");
sb.append(" AsyncPercentile");
sb.append("");
sb.append(" AsyncAvg");
sb.append("");
for (DataMetrics metrics : dataMetricsList) {
sb.append("");
sb.append(" " + metrics.getName());
sb.append("");
sb.append(" " + metrics.getSyncCall());
sb.append("");
sb.append(" " + metrics.getSyncPercent());
sb.append("");
sb.append(" " + metrics.getSyncAvg());
sb.append("");
sb.append(" " + metrics.getSyncMax());
sb.append("");
sb.append(" " + metrics.getAsyncCall());
sb.append("");
sb.append(" " + metrics.getAsyncPercent());
sb.append("");
sb.append(" " + metrics.getAsyncAvg());
sb.append("");
sb.append("");
}
sb.append("");
sb.append("");
sb.append("");
System.out.println(sb.toString());Somehow, the code looks pretty ugly to me in the way HTML and CSS are being used within
StringBuilder. I am opting for code review to see whether we can improve anything here. Is there any better way of writing this code?Solution
-
How about extracting the
-
You should write helper methods, that do the 'heavy lifting' for you:
Please note, that if you are using
If you want to get even more expressive you should take a look at existing template engines. They are optimized and mostly easy to use.
Suggesting mustache:
If you are using mustache, you can write a template like this:
and then render it via e.g.
It depends on your use case, of course. If all you ever want is to render a single table, you are fine with
How about extracting the
style=""s into the head?sb.append("" +
"td { padding: 6px; border: 1px solid #ccc; text-align: left; }" +
"th { background: #333; color: white; font-weight: bold; padding: 6px; border: 1px solid #ccc; text-align: left;}" +
"");-
You should write helper methods, that do the 'heavy lifting' for you:
void appendTag(StringBuilder sb, String tag, String contents) {
sb.append('');
sb.append(contents);
sb.append("');
}
void appendDataCell(StringBuilder sb, String contents) {
appendTag(sb, "td", contents);
}
void appendHeaderCell(StringBuilder sb, String contents) {
appendTag(sb, "th", contents);
}Please note, that if you are using
StringBuilder you should not concatenate strings with +. You want to get rid of string concatenation, not do it.If you want to get even more expressive you should take a look at existing template engines. They are optimized and mostly easy to use.
Suggesting mustache:
If you are using mustache, you can write a template like this:
Table
...
....
{{#metrics}}
{{getName}}
...
{{/metrics}}
and then render it via e.g.
public static void main(String[] args) throws IOException {
HashMap scopes = new HashMap();
scopes.put("metrics", dataMetricsList);
Writer writer = new OutputStreamWriter(System.out);
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(new StringReader(getTemplateCodeFromAbove()), "example");
mustache.execute(writer, scopes);
writer.flush();
}It depends on your use case, of course. If all you ever want is to render a single table, you are fine with
StringBuilder. But if you find yourself repeating this, get an external library for it.Code Snippets
sb.append("<style>" +
"td { padding: 6px; border: 1px solid #ccc; text-align: left; }" +
"th { background: #333; color: white; font-weight: bold; padding: 6px; border: 1px solid #ccc; text-align: left;}" +
"</style>");void appendTag(StringBuilder sb, String tag, String contents) {
sb.append('<').append(tag).append('>');
sb.append(contents);
sb.append("</").append(tag).append('>');
}
void appendDataCell(StringBuilder sb, String contents) {
appendTag(sb, "td", contents);
}
void appendHeaderCell(StringBuilder sb, String contents) {
appendTag(sb, "th", contents);
}<html>
<head>
<title>Table</title>
<style>...</style>
</head>
<body>
<table>
<tr><th>....</th></tr>
{{#metrics}}
<tr>
<td>{{getName}}</td>
...
</tr>
{{/metrics}}
</body>
</html>public static void main(String[] args) throws IOException {
HashMap<String, Object> scopes = new HashMap<String, Object>();
scopes.put("metrics", dataMetricsList);
Writer writer = new OutputStreamWriter(System.out);
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(new StringReader(getTemplateCodeFromAbove()), "example");
mustache.execute(writer, scopes);
writer.flush();
}Context
StackExchange Code Review Q#63331, answer score: 21
Revisions (0)
No revisions yet.