66

I would like to organize information like this:

The information is organized with cells, whereas with System.out.println the information would be very disorganized.

or this

5
  • 6
    +1. Not a bad question. If someone has a good library for this, please recommend. Otherwise, look at System.out.format Commented Mar 5, 2013 at 3:32
  • 1
    You could check out this for an example Commented Mar 5, 2013 at 3:33
  • Your best bets are mainly to use System.out.printf(...) and the equivalent System.out.format(...). Commented Mar 5, 2013 at 3:34
  • Not an ASCII table, but similar question here .. stackoverflow.com/questions/5551186/… Commented Jan 27, 2015 at 20:55
  • table mysnort lmao Commented Sep 14, 2019 at 3:10

13 Answers 13

100

You can use System.out.format() or System.out.printf() (printf internally simply invokes format so both methods give same results).

Below you will find example which will align text to left and fill unused places with spaces. Aligning String to left can be achieved with %-15s, which means:

  • % reserve (placeholder)
  • 15 "places" for characters
  • s of String data-type
  • - and start printing them from left.

If you want to handle digits use d suffix like %-4d to reserve minimum 4 "spaces", number will be printed from left side of that "column".

BTW printf doesn't automatically add line separators after printed data, so if we want to move cursor to next line we need to do it ourselves. We can use \r or \n, or let Formatter generate OS dependent line separator (like for Windows \r\n) with %n (note: this "placeholder" doesn't require any data as arguments, Java will provide correct sequence based on OS).

You can find more info about supported syntax at documentation of Formatter class.

String leftAlignFormat = "| %-15s | %-4d |%n";

System.out.format("+-----------------+------+%n");
System.out.format("| Column name     | ID   |%n");
System.out.format("+-----------------+------+%n");
for (int i = 0; i < 5; i++) {
    System.out.format(leftAlignFormat, "some data" + i, i * i);
}
System.out.format("+-----------------+------+%n");

output

+-----------------+------+
| Column name     | ID   |
+-----------------+------+
| some data0      | 0    |
| some data1      | 1    |
| some data2      | 4    |
| some data3      | 9    |
| some data4      | 16   |
+-----------------+------+
Sign up to request clarification or add additional context in comments.

2 Comments

¡¡A perfect answer!! ¡Thank you so much! i could do that i wanted =)
For fixed requirements, this solution is perfect. For more real life use cases, a library is more appropriate. See this answer: stackoverflow.com/a/35961774/363573.
45

Try this alternative: asciitable.

It offers several implementations of a text table, originally using ASCII and UTF-8 characters for borders.

Here is a sample table:

    ┌──────────────────────────────────────────────────────────────────────────┐
    │ Table Heading                                                            │
    ├──────────────────┬──────────────────┬──────────────────┬─────────────────┤
    │ first row (col1) │ with some        │ and more         │ even more       │
    │                  │ information      │ information      │                 │
    ├──────────────────┼──────────────────┼──────────────────┼─────────────────┤
    │ second row       │ with some        │ and more         │ even more       │
    │ (col1)           │ information      │ information      │                 │
    │                  │ (col2)           │ (col3)           │                 │
    └──────────────────┴──────────────────┴──────────────────┴─────────────────┘

Find the latest version: http://mvnrepository.com/artifact/de.vandermeer/asciitable

See also: https://stackoverflow.com/a/39806611/363573

1 Comment

Plus, they have some beautiful table designs there.
21

My class I created specifically for doing this is completely dynamic: https://github.com/2xsaiko/crogamp/blob/master/src/com/github/mrebhan/crogamp/cli/TableList.java

You can use it like this:

TableList tl = new TableList(3, "ID", "String 1", "String 2").sortBy(0).withUnicode(true);
// from a list
yourListOrWhatever.forEach(element -> tl.addRow(element.getID(), element.getS1(), element.getS2()));
// or manually
tl.addRow("Hi", "I am", "Bob");

tl.print();

It will look like this with unicode chars (note: will look better in console since all chars are equally wide):

┌─────────┬─────────────────────────────────────────────────────────────────────────┬────────────────────────────┐
│ Command │ Description                                                             │ Syntax                     │
┢━━━━━━━━━╈━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╈━━━━━━━━━━━━━━━━━━━━━━━━━━━━┪
┃ bye     ┃ Quits the application.                                                  ┃                            ┃
┃ ga      ┃ Adds the specified game.                                                ┃ <id> <description> <path>  ┃
┃ gl      ┃ Lists all currently added games                                         ┃ [pattern]                  ┃
┃ gr      ┃ Rebuilds the files of the currently active game.                        ┃                            ┃
┃ gs      ┃ Selects the specified game.                                             ┃ <id>                       ┃
┃ help    ┃ Lists all available commands.                                           ┃ [pattern]                  ┃
┃ license ┃ Displays licensing info.                                                ┃                            ┃
┃ ma      ┃ Adds a mod to the currently active game.                                ┃ <id> <file>                ┃
┃ md      ┃ Deletes the specified mod and removes all associated files.             ┃ <id>                       ┃
┃ me      ┃ Toggles if the selected mod is active.                                  ┃ <id>                       ┃
┃ ml      ┃ Lists all mods for the currently active game.                           ┃ [pattern]                  ┃
┃ mm      ┃ Moves the specified mod to the specified position in the priority list. ┃ <id> <position>            ┃
┃ top kek ┃ Test command. Do not use, may cause death and/or destruction            ┃                            ┃
┃ ucode   ┃ Toggles advanced unicode. (Enhanced characters)                         ┃ [on|true|yes|off|false|no] ┃
┗━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

And with unicode chars off (omit the .withUnicode(true)):

Command | Description                                                             | Syntax                    
--------+-------------------------------------------------------------------------+---------------------------
bye     | Quits the application.                                                  |                           
ga      | Adds the specified game.                                                | <id> <description> <path> 
gl      | Lists all currently added games                                         | [pattern]                 
gr      | Rebuilds the files of the currently active game.                        |                           
gs      | Selects the specified game.                                             | <id>                      
help    | Lists all available commands.                                           | [pattern]                 
license | Displays licensing info.                                                |                           
ma      | Adds a mod to the currently active game.                                | <id> <file>               
md      | Deletes the specified mod and removes all associated files.             | <id>                      
me      | Toggles if the selected mod is active.                                  | <id>                      
ml      | Lists all mods for the currently active game.                           | [pattern]                 
mm      | Moves the specified mod to the specified position in the priority list. | <id> <position>           
top kek | Test command. Do not use, may cause death and/or destruction            |                           
ucode   | Toggles advanced unicode. (Enhanced characters)                         | [on|true|yes|off|false|no]

1 Comment

Also have a look here for more unicodes: fileformat.info/info/unicode/block/box_drawing/images.htm
5

use System.out.printf()

For example,

String s = //Any string
System.out.printf(%10s, s);

will print out the contents of String s, taking up exactly 10 characters. So if you want a table, just make sure each cell in the table is printed out to the same length. Also notice that printf() doesn't print a new line, so you'll have to print it yourself.

Comments

4

You could use java-ascii-table. See also the author's site.

1 Comment

java-ascii-table seems abandonned. See this answer for an alternative: stackoverflow.com/a/35961774/363573
3

I do it this way

Example: Print a table with the values of x² - x + 41 for 1 < x < 42

public class PrimeEquation
{
    public static void main(String[] args)
    {
        String header = "";
        header += formatDiv("a-----b-------------b----------c\n");
        header += formatRow("|  x  | x² - x + 41 | Is Prime |\n");
        header += formatDiv("d-----e-------------e----------f\n");
        System.out.print(header);

        for (int x = 2; x <= 41; x++)
        {
            int y = primeEquation(x);
            String str1 = String.format("| %3d | %11d | %8b |", x, y, MyPrimes.isPrime(y));
            System.out.println(formatRow(str1));
        }

        System.out.println(formatDiv("g-----h-------------h----------i"));
    }

    public static int primeEquation(int x)
    {
        return (x*x) - x + 41;
    }

    public static String formatRow(String str)
    {
        return str.replace('|', '\u2502');
    }

    public static String formatDiv(String str)
    {
        return str.replace('a', '\u250c')
                .replace('b', '\u252c')
                .replace('c', '\u2510')
                .replace('d', '\u251c')
                .replace('e', '\u253c')
                .replace('f', '\u2524')
                .replace('g', '\u2514')
                .replace('h', '\u2534')
                .replace('i', '\u2518')
                .replace('-', '\u2500');
    }
}

Output:

Table

Comments

1

You can use string.format() with correct method Code could look something like this i guess

StringBuilder sb=new StringBuilder();

for(int i = 1; i <= numberOfColumns; i++)
 {
       sb.append(String.format(%-10s,rsMetaData.getColumnLabel(i);
 }

As of library i dont think there is any that would do the job, however i might be mistaken! will actually do research on it

Also have a look at this http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html#syntax

Comments

1

This also works pretty well http://sourceforge.net/projects/texttablefmt/. Apache licensed too.

1 Comment

texttablefmt doesn't seem to be available on Maven. Here is another library available on Maven: stackoverflow.com/a/35961774/363573
1

You can use Spring Shell utility class org.springframework.shell.table.TableModel:

      TableModel model = new BeanListTableModel<>(portConfigurations, headers);
    TableBuilder tableBuilder = new TableBuilder(model);
    tableBuilder.addFullBorder(BorderStyle.oldschool);
    //TableUtils.applyStyle(tableBuilder);
    return tableBuilder.build().render(100);

Comments

1

Just in case somebody needs this type of table:

+----+----+----+----+----+
|  1 |  2 |  3 |  4 |  5 |
+----+----+----+----+----+
|  6 |  7 |  8 |  9 | 10 |
+----+----+----+----+----+
| 11 | 12 | 13 | 14 | 15 |
+----+----+----+----+----+
| 16 | 17 | 18 | 19 | 20 |
+----+----+----+----+----+
| 21 | 22 | 23 | 24 | 25 |
+----+----+----+----+----+

Here is my solution:

public class TableShape {

    public static void main(String[] args) {
        int width_and_height=5;
        int count=1; 

        for(int i=0;i<width_and_height ; i++) {
            System.out.println("+----+----+----+----+----+");

            for(int j=0;j<width_and_height;j++) {
                System.out.format("| %2d ", count++);

                if(j==width_and_height-1) { // closing | for last column
                    System.out.print("|");
                }
            }
            System.out.println();
            if(i==width_and_height-1) { // closing line for last row
                System.out.print("+----+----+----+----+----+");
            }
        }

    }
}

Comments

1

Using fragments of the idea from @David Celi, I create my own solution.

This is my solution.

I hope it help.

Thanks for @David Celi

private static class ConsolePanel {

public static void main(String[] args) {

  fullPanel(21, 5, 3, 3,
            "myTitcccle",
            "myBoxxxdy", "myBvvy2", "myBvvy2"
  );
}


public static void simplePanel(
     int scale,
     int margin,
     int upSpace,
     int downSpace,
     String... titleAndOthers) {

  fullPanel(
       21,
       5,
       1,
       1,
       titleAndOthers
  );
}

public static void simplePanelWithSize(
     int scale,
     int margin,
     int upSpace,
     int downSpace,
     String... titleAndOthers) {

  fullPanel(
       scale,
       5,
       1,
       1,
       titleAndOthers
  );
}

public static void fullPanel(
     int scale,
     int margin,
     int upSpace,
     int downSpace,
     String... titleAndOthers) {

  var marginLimitedBySize = Math.min(margin, scale);

  // scale + margin discrepacies eliminated
  if (marginLimitedBySize % 2 != 0) -- marginLimitedBySize;
  if (scale % 2 != 0) ++ scale;

  int fullSize = (scale * 2) - marginLimitedBySize;
  if (fullSize % 2 == 0) ++ fullSize;
  else -- fullSize;

  var internalTextSpace = String.valueOf(fullSize);

  var marginAsString = " ".repeat(marginLimitedBySize);
  var upperSpace = "\n".repeat(upSpace);
  var lowerSpace = "\n".repeat(downSpace);
  var baseline =
       "_".repeat(scale)
          .replace('_', myFont.BASE_LINE.code);

  var divider =
       "_".repeat(scale)
          .replace('_', myFont.BASE_LINE_BOLD.code);

  var upperLineString =
       myFont.UPPER_LEFT_CORNER.code + baseline +
       myFont.MIDDLE_CENTER.code + baseline +
       myFont.UPPER_RIGHT_CORNER.code + "\n";

  var middleLineString =
       myFont.MIDDLE_LEFT.code + divider +
       myFont.MIDDLE_CENTER.code + divider +
       myFont.MIDDLE_RIGHT.code + "\n";

  var bottonLineString =
       myFont.LOWER_LEFT_CORNER.code + baseline +
       myFont.MIDDLE_CENTER.code + baseline +
       myFont.LOWER_RIGHT_CORNER.code + "\n";

  var textBuilder = new StringBuilder();
  textBuilder
       .append(upperSpace)
       .append(upperLineString)

       .append(myFont.MIDDLE_FACE.code )
       .append("%s%%-%ss".formatted(marginAsString, internalTextSpace))
       .append(myFont.MIDDLE_FACE.code )
       .append("\n" )
       .append(middleLineString)
  ;

  // "-1" Because the first element in the Array was used as title
  for (int i = titleAndOthers.length - 1; i > 0; i--)
    textBuilder.append(
         simpleLineStyle(
              "|%s%%-%ss|\n".formatted(marginAsString, internalTextSpace)));

  textBuilder
       .append(bottonLineString)
       .append(lowerSpace);
  System.out.printf(textBuilder.toString(), (Object[]) titleAndOthers);
}

 private enum myFont {

  MIDDLE_CENTER('\u2501'),
  BASE_LINE('\u2500'),
  BASE_LINE_BOLD('\u2501'),
  UPPER_LEFT_CORNER('\u250F'),
  UPPER_RIGHT_CORNER('\u2513'),
  MIDDLE_LEFT('\u2523'),
  MIDDLE_RIGHT('\u252B'),
  MIDDLE_FACE('\u2502'),
  LOWER_LEFT_CORNER('\u2517'),
  LOWER_RIGHT_CORNER('\u251B');

  private final char code;

  myFont(char code) {

    this.code = code;
  }
}

}

Comments

0

TUIAWT lets you use AWT components in a console window. It doesn't look like it supports List or Table, though, but it may give you a starting point.

1 Comment

As of this writing, the last update to TUIAWT seems to be in March 2015.
0

I attempted a solution for this with these features

  • Dynamic width of columns
  • If width beyond max, then wrap it to next line.

Here is the simple pure java solution which you can use as per your need.

Output will look something like this.

+----+------------+--------------------------------+-----+--------------------------------+
| id | First Name | Last Name                      | Age | Profile                        |
+----+------------+--------------------------------+-----+--------------------------------+
| 1  | John       | Johnson                        | 45  | My name is John Johnson. My id |
|    |            |                                |     |  is 1. My age is 45.           |
|    |            |                                |     |                                |
| 2  | Tom        |                                | 35  | My name is Tom. My id is 2. My |
|    |            |                                |     |  age is 35.                    |
|    |            |                                |     |                                |
| 3  | Rose       | Johnson Johnson Johnson Johnso | 22  | My name is Rose Johnson. My id |
|    |            | n Johnson Johnson Johnson John |     |  is 3. My age is 22.           |
|    |            | son Johnson Johnson            |     |                                |
|    |            |                                |     |                                |
| 4  | Jimmy      | Kimmel                         |     | My name is Jimmy Kimmel. My id |
|    |            |                                |     |  is 4. My age is not specified |
|    |            |                                |     | . I am the host of the late ni |
|    |            |                                |     | ght show. I am not fan of Matt |
|    |            |                                |     |  Damon.                        |
|    |            |                                |     |                                |
+----+------------+--------------------------------+-----+--------------------------------+

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.