How to print a table of information in Java
Asked Answered
K

6

16

I'm trying to print a table in Java and I was wondering what is the best way to do this?

I've tried printing new lines and using \t to make contents line up but it doesn't work. Is there a method which does this or a better way?

Kitts answered 7/9, 2013 at 11:6 Comment(1)
Look at string format with alignment.Ecg
R
40

You can use System.out.format(...)

Example:

final Object[][] table = new String[4][];
table[0] = new String[] { "foo", "bar", "baz" };
table[1] = new String[] { "bar2", "foo2", "baz2" };
table[2] = new String[] { "baz3", "bar3", "foo3" };
table[3] = new String[] { "foo4", "bar4", "baz4" };

for (final Object[] row : table) {
    System.out.format("%15s%15s%15s%n", row);
}

Result:

        foo            bar            baz
       bar2           foo2           baz2
       baz3           bar3           foo3
       foo4           bar4           baz4

Or use the following code for left-aligned output:

System.out.format("%-15s%-15s%-15s%n", row);
Roydd answered 7/9, 2013 at 11:16 Comment(9)
is it possible to do this for an arbitrary number of elements?Halette
Sorry corvid, i don't understand your question. Can you explain it better?Roydd
Is there a way to left alight this rather than right?Languid
Sure, use System.out.format("%-15s%-15s%-15s\n", row);Roydd
@Halette - To answer your question 2 years later, the example given already shows how to print an arbitrary number of table elements. The loop is read, "For row in table" - it goes until it cannot find a next row, thus you do not need to know exactly how many elements there are. :)Abbieabbot
System.out.format("%-15s%-15s%-15s\n", row); it expects three strings, but only one (row) is provided. Isn't it an error? It certainly gets highlighted as such for me in IDE.Trickery
@Abbieabbot what if the array to print contains 500 elements? We can't very well to manually repeat the %15s bit 500 times?Trickery
@Trickery row is an Object[], so it shouldn't be an errorSelfdelusion
@Trickery I don't really know a good answer to make this work for an arbitrary number of elements in a row, but I would try seeing if you could make the "%15s%15s%15s%n" a variable that you can loop and manipulate, and then try passing in the string variable as the format instead. Don't know if this helps you after so long, but if it does...Somber
T
17

General function to table-format a list of arrays:

public static String formatAsTable(List<List<String>> rows)
{
    int[] maxLengths = new int[rows.get(0).size()];
    for (List<String> row : rows)
    {
        for (int i = 0; i < row.size(); i++)
        {
            maxLengths[i] = Math.max(maxLengths[i], row.get(i).length());
        }
    }

    StringBuilder formatBuilder = new StringBuilder();
    for (int maxLength : maxLengths)
    {
        formatBuilder.append("%-").append(maxLength + 2).append("s");
    }
    String format = formatBuilder.toString();

    StringBuilder result = new StringBuilder();
    for (List<String> row : rows)
    {
        result.append(String.format(format, row.toArray(new String[0]))).append("\n");
    }
    return result.toString();
}

Usage:

List<List<String>> rows = new ArrayList<>();
List<String> headers = Arrays.asList("Database", "Maintainer", "First public release date", "Latest stable version", "Latest release date");
rows.add(headers);
rows.add(Arrays.asList("4D (4th Dimension)", "4D S.A.S.", "1984", "v16.0", "2017-01-10"));
rows.add(Arrays.asList("ADABAS", "Software AG", "1970", "8.1", "2013-06"));
rows.add(Arrays.asList("Adaptive Server Enterprise", "SAP AG", "1987", "16.0", "2015"));
rows.add(Arrays.asList("Apache Derby", "Apache", "2004", "10.14.1.0", "2017-10-22"));

System.out.println(formatAsTable(rows));

The result:

Database                    Maintainer   First public release date  Latest stable version  Latest release date  
4D (4th Dimension)          4D S.A.S.    1984                       v16.0                  2017-01-10           
ADABAS                      Software AG  1970                       8.1                    2013-06              
Adaptive Server Enterprise  SAP AG       1987                       16.0                   2015                 
Apache Derby                Apache       2004                       10.14.1.0              2017-10-22    
Titograd answered 1/6, 2018 at 19:7 Comment(0)
L
5

This is one way to do it:

public class StoreItem {

    private String itemName;
    private double price;
    private int quantity;


    public StoreItem(String itemName, double price, int quantity) {
        this.setItemName(itemName);
        this.setPrice(price);
        this.setQuantity(quantity);
    }


    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }


    public static void printInvoiceHeader() {
        System.out.println(String.format("%30s %25s %10s %25s %10s", "Item", "|", "Price($)", "|", "Qty"));
        System.out.println(String.format("%s", "----------------------------------------------------------------------------------------------------------------"));
    }
    public void printInvoice() {
        System.out.println(String.format("%30s %25s %10.2f %25s %10s", this.getItemName(), "|", this.getPrice(), "|", this.getQuantity()));
    }

    public static List<StoreItem> buildInvoice() {
        List<StoreItem> itemList = new ArrayList<>();
        itemList.add(new StoreItem("Nestle Decaff Coffee", 759.99, 2));
        itemList.add(new StoreItem("Brown's Soft Tissue Paper", 15.80, 2));
        itemList.add(new StoreItem("LG 500Mb External Drive", 700.00, 2));
        return itemList;
    }

    public static void main (String[] args) {

        StoreItem.printInvoiceHeader();
        StoreItem.buildInvoice().forEach(StoreItem::printInvoice);
     }
}

Output:

enter image description here

Lenny answered 14/10, 2017 at 16:32 Comment(0)
A
1

Write a function which pads a string to your desired column-length with spaces. This can be a static helper, and you can create a class StrUtils or similar to hold it.

(There may also be Apache or other libraries with String helpers/utils to do this for you.)

Long-term, if you're outputting tabular data you could consider exporting CSV (for Excel etc) or XML. But these are for typical long-term business requirements, not just a quick to-screen output.

Abruption answered 7/9, 2013 at 11:12 Comment(1)
ok thanks for your help I'll have a look at some string functionsKitts
H
1

I think using J-Text-Utils to output the table for you would be a convenient way. Through this small library, you do not need to reinvent the wheel. You just input your data and it will take care of formatting for you.

This is an example from their Google Code site:

String[] columnNames = {
"First Name",
"Last Name",
"Sport",
"# of Years",
"Vegetarian"};

Object[][] data = {
{"Kathy", "Smith",
"Snowboarding", new Integer(5), new Boolean(false)},
{"John", "Doe",
"Rowing", new Integer(3), new Boolean(true)},
{"Sue", "Black",
"Knitting", new Integer(2), new Boolean(false)},
{"Jane", "White",
"Speed reading", new Integer(20), new Boolean(true)}, {"Joe", "Brown",
"Pool", new Integer(10), new Boolean(false)}
};

TextTable tt = new TextTable(columnNames, data);
// this adds the numbering on the left
tt.setAddRowNumbering(true);
// sort by the first column
tt.setSort(0);
tt.printTable();

The Output:

Output

Houston answered 5/11, 2021 at 12:57 Comment(0)
G
0

Library for printing Java objects as Markdown / CSV / HTML table using reflection: https://github.com/mjfryc/mjaron-etudes-java

dependencies {
    implementation 'io.github.mjfryc:mjaron-etudes-java:0.2.1'
}
Cat[] cats = {cat0, cat1};
Table.render(cats, Cat.class).markdown().to(System.out).run();

Sample Markdown output:

| name | legsCount | lazy  | topSpeed |
|------|-----------|-------|----------|
| John | 4         | true  | 35.24    |
| Bob  | 5         | false | 75.0     |
Gault answered 27/7, 2021 at 21:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.