I'm getting results from a database and want to output the data as a table in Java's standard output
I've tried using \t but the first column I want is very variable in length.
Is there a way to display this in a nice table like output?
I'm getting results from a database and want to output the data as a table in Java's standard output
I've tried using \t but the first column I want is very variable in length.
Is there a way to display this in a nice table like output?
Use System.out.format
. You can set lengths of fields like this:
System.out.format("%32s%10d%16s", string1, int1, string2);
This pads string1
, int1
, and string2
to 32, 10, and 16 characters, respectively.
See the Javadocs for java.util.Formatter
for more information on the syntax (System.out.format
uses a Formatter
internally).
Using j-text-utils you may print to console a table like:
And it as simple as:
TextTable tt = new TextTable(columnNames, data);
tt.printTable();
The API also allows sorting and row numbering ...
I may be very late for the Answer but here a simple and generic solution
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class TableGenerator {
private int PADDING_SIZE = 2;
private String NEW_LINE = "\n";
private String TABLE_JOINT_SYMBOL = "+";
private String TABLE_V_SPLIT_SYMBOL = "|";
private String TABLE_H_SPLIT_SYMBOL = "-";
public String generateTable(List<String> headersList, List<List<String>> rowsList,int... overRiddenHeaderHeight)
{
StringBuilder stringBuilder = new StringBuilder();
int rowHeight = overRiddenHeaderHeight.length > 0 ? overRiddenHeaderHeight[0] : 1;
Map<Integer,Integer> columnMaxWidthMapping = getMaximumWidhtofTable(headersList, rowsList);
stringBuilder.append(NEW_LINE);
stringBuilder.append(NEW_LINE);
createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping);
stringBuilder.append(NEW_LINE);
for (int headerIndex = 0; headerIndex < headersList.size(); headerIndex++) {
fillCell(stringBuilder, headersList.get(headerIndex), headerIndex, columnMaxWidthMapping);
}
stringBuilder.append(NEW_LINE);
createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping);
for (List<String> row : rowsList) {
for (int i = 0; i < rowHeight; i++) {
stringBuilder.append(NEW_LINE);
}
for (int cellIndex = 0; cellIndex < row.size(); cellIndex++) {
fillCell(stringBuilder, row.get(cellIndex), cellIndex, columnMaxWidthMapping);
}
}
stringBuilder.append(NEW_LINE);
createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping);
stringBuilder.append(NEW_LINE);
stringBuilder.append(NEW_LINE);
return stringBuilder.toString();
}
private void fillSpace(StringBuilder stringBuilder, int length)
{
for (int i = 0; i < length; i++) {
stringBuilder.append(" ");
}
}
private void createRowLine(StringBuilder stringBuilder,int headersListSize, Map<Integer,Integer> columnMaxWidthMapping)
{
for (int i = 0; i < headersListSize; i++) {
if(i == 0)
{
stringBuilder.append(TABLE_JOINT_SYMBOL);
}
for (int j = 0; j < columnMaxWidthMapping.get(i) + PADDING_SIZE * 2 ; j++) {
stringBuilder.append(TABLE_H_SPLIT_SYMBOL);
}
stringBuilder.append(TABLE_JOINT_SYMBOL);
}
}
private Map<Integer,Integer> getMaximumWidhtofTable(List<String> headersList, List<List<String>> rowsList)
{
Map<Integer,Integer> columnMaxWidthMapping = new HashMap<>();
for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) {
columnMaxWidthMapping.put(columnIndex, 0);
}
for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) {
if(headersList.get(columnIndex).length() > columnMaxWidthMapping.get(columnIndex))
{
columnMaxWidthMapping.put(columnIndex, headersList.get(columnIndex).length());
}
}
for (List<String> row : rowsList) {
for (int columnIndex = 0; columnIndex < row.size(); columnIndex++) {
if(row.get(columnIndex).length() > columnMaxWidthMapping.get(columnIndex))
{
columnMaxWidthMapping.put(columnIndex, row.get(columnIndex).length());
}
}
}
for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) {
if(columnMaxWidthMapping.get(columnIndex) % 2 != 0)
{
columnMaxWidthMapping.put(columnIndex, columnMaxWidthMapping.get(columnIndex) + 1);
}
}
return columnMaxWidthMapping;
}
private int getOptimumCellPadding(int cellIndex,int datalength,Map<Integer,Integer> columnMaxWidthMapping,int cellPaddingSize)
{
if(datalength % 2 != 0)
{
datalength++;
}
if(datalength < columnMaxWidthMapping.get(cellIndex))
{
cellPaddingSize = cellPaddingSize + (columnMaxWidthMapping.get(cellIndex) - datalength) / 2;
}
return cellPaddingSize;
}
private void fillCell(StringBuilder stringBuilder,String cell,int cellIndex,Map<Integer,Integer> columnMaxWidthMapping)
{
int cellPaddingSize = getOptimumCellPadding(cellIndex, cell.length(), columnMaxWidthMapping, PADDING_SIZE);
if(cellIndex == 0)
{
stringBuilder.append(TABLE_V_SPLIT_SYMBOL);
}
fillSpace(stringBuilder, cellPaddingSize);
stringBuilder.append(cell);
if(cell.length() % 2 != 0)
{
stringBuilder.append(" ");
}
fillSpace(stringBuilder, cellPaddingSize);
stringBuilder.append(TABLE_V_SPLIT_SYMBOL);
}
public static void main(String[] args) {
TableGenerator tableGenerator = new TableGenerator();
List<String> headersList = new ArrayList<>();
headersList.add("Id");
headersList.add("F-Name");
headersList.add("L-Name");
headersList.add("Email");
List<List<String>> rowsList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
List<String> row = new ArrayList<>();
row.add(UUID.randomUUID().toString());
row.add(UUID.randomUUID().toString());
row.add(UUID.randomUUID().toString());
row.add(UUID.randomUUID().toString());
rowsList.add(row);
}
System.out.println(tableGenerator.generateTable(headersList, rowsList));
}
}
With this kind of Output
+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+
| Id | F-Name | L-Name | Email |
+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+
| 70a56f25-d42a-499c-83ac-50188c45a0ac | aa04285e-c135-46e2-9f90-988bf7796cd0 | ac495ba7-d3c7-463c-8c24-9ffde67324bc | f6b5851b-41e0-4a4e-a237-74f8e0bff9ab |
| 6de181ca-919a-4425-a753-78d2de1038ef | c4ba5771-ccee-416e-aebd-ef94b07f4fa2 | 365980cb-e23a-4513-a895-77658f130135 | 69e01da1-078e-4934-afb0-5afd6ee166ac |
| f3285f33-5083-4881-a8b4-c8ae10372a6c | 46df25ed-fa0f-42a4-9181-a0528bc593f6 | d24016bf-a03f-424d-9a8f-9a7b7388fd85 | 4b976794-aac1-441e-8bd2-78f5ccbbd653 |
| ab799acb-a582-45e7-ba2f-806948967e6c | d019438d-0a75-48bc-977b-9560de4e033e | 8cb2ad11-978b-4a67-a87e-439d0a21ef99 | 2f2d9a39-9d95-4a5a-993f-ceedd5ff9953 |
| 78a68c0a-a824-42e8-b8a8-3bdd8a89e773 | 0f030c1b-2069-4c1a-bf7d-f23d1e291d2a | 7f647cb4-a22e-46d2-8c96-0c09981773b1 | 0bc944ef-c1a7-4dd1-9eef-915712035a74 |
+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+
I've created a project that can build much advanced table views. If you supposed to print the table, the width of the table going to have a limit. I have applied it in one of my own project to get a customer invoice print. Following is an example of the print view.
PLATINUM COMPUTERS(PVT) LTD
NO 20/B, Main Street, Kandy, Sri Lanka.
Land: 812254630 Mob: 712205220 Fax: 812254639
CUSTOMER INVOICE
+-----------------------+----------------------+
|INFO |CUSTOMER |
+-----------------------+----------------------+
|DATE: 2015-9-8 |ModernTec Distributors|
|TIME: 10:53:AM |MOB: +94719530398 |
|BILL NO: 12 |ADDRES: No 25, Main St|
|INVOICE NO: 458-80-108 |reet, Kandy. |
+-----------------------+----------------------+
| SELLING DETAILS |
+-----------------+---------+-----+------------+
|ITEM | PRICE($)| QTY| VALUE|
+-----------------+---------+-----+------------+
|Optical mouse | 120.00| 20| 2400.00|
|Gaming keyboard | 550.00| 30| 16500.00|
|320GB SATA HDD | 220.00| 32| 7040.00|
|500GB SATA HDD | 274.00| 13| 3562.00|
|1TB SATA HDD | 437.00| 11| 4807.00|
|RE-DVD ROM | 144.00| 29| 4176.00|
|DDR3 4GB RAM | 143.00| 13| 1859.00|
|Blu-ray DVD | 94.00| 28| 2632.00|
|WR-DVD | 122.00| 34| 4148.00|
|Adapter | 543.00| 28| 15204.00|
+-----------------+---------+-----+------------+
| RETURNING DETAILS |
+-----------------+---------+-----+------------+
|ITEM | PRICE($)| QTY| VALUE|
+-----------------+---------+-----+------------+
|320GB SATA HDD | 220.00| 4| 880.00|
|WR-DVD | 122.00| 7| 854.00|
|1TB SATA HDD | 437.00| 7| 3059.00|
|RE-DVD ROM | 144.00| 4| 576.00|
|Gaming keyboard | 550.00| 6| 3300.00|
|DDR3 4GB RAM | 143.00| 7| 1001.00|
+-----------------+---------+-----+------------+
GROSS 59,928.00
DISCOUNT(5%) 2,996.40
RETURN 9,670.00
PAYABLE 47,261.60
CASH 20,000.00
CHEQUE 15,000.00
CREDIT(BALANCE) 12,261.60
--------------------- ---------------------
CASH COLLECTOR GOODS RECEIVED BY
soulution by clough.com
This is the code for above print view and you can find the library (Wagu) in here.
Check this out. The author provides a simple but elegant solution which doesn't require any 3rd party library. http://www.ksmpartners.com/2013/08/nicely-formatted-tabular-output-in-java/
Because most of solutions is bit outdated I could also suggest asciitable which already available in maven (de.vandermeer:asciitable:0.3.2
) and may produce very complicated configurations.
And usage still looks easy:
AsciiTable at = new AsciiTable();
at.addRule();
at.addRow("row 1 col 1", "row 1 col 2");
at.addRule();
at.addRow("row 2 col 1", "row 2 col 2");
at.addRule();
System.out.println(at.render()); // Finally, print the table to standard out.
public class Main {
public static void main(String args[]) {
String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
System.out.format(format, "A", "AA", "AAA");
System.out.format(format, "B", "", "BBBBB");
System.out.format(format, "C", "CCCCC", "CCCCCCCC");
String ex[] = { "E", "EEEEEEEEEE", "E" };
System.out.format(String.format(format, (Object[]) ex));
}
}
differece in sizes of input doesnt effect the output
Check out the class java.util.Formatter.