Output dalam format tabel di System.out Java

91

Saya mendapatkan hasil dari database dan ingin mengeluarkan data sebagai tabel dalam keluaran standar Java

Saya sudah mencoba menggunakan \ t tetapi kolom pertama yang saya inginkan sangat bervariasi.

Apakah ada cara untuk menampilkan ini dalam tabel yang bagus seperti keluaran?

Chris
sumber

Jawaban:

145

Gunakan System.out.format. Anda dapat mengatur panjang bidang seperti ini:

System.out.format("%32s%10d%16s", string1, int1, string2);

Bantalan ini string1, int1dan string2untuk 32, 10, dan 16 karakter masing-masing.

Lihat Javadocs untuk java.util.Formatterinformasi lebih lanjut tentang sintaks ( System.out.formatmenggunakan secara Formatterinternal).

Michael Myers
sumber
1
Terima kasih hanya apa yang saya butuhkan! Saya hanya akan menambahkan saya perlu meletakkan \ n di akhir untuk menghasilkan baris baru setiap kali, jika ada orang lain yang menemukan masalah itu.
Chris
19
Atau, lebih baik, a %n- secara otomatis diterjemahkan ke dalam terminator baris default sistem.
Michael Myers
1
Bagaimana saya bisa membuat perataan kiri dalam tabel string?
Mike
16
Rata kiri: System.out.format ("% - 2s% 10d% -16s", string1, int1, string2);
Mike
1
Jika saya ingin membuat rata tengah, bagaimana cara melakukannya?
pratnala
36

Menggunakan j-text-utils Anda dapat mencetak ke konsol tabel seperti: masukkan deskripsi gambar di sini

Dan sesederhana itu:

TextTable tt = new TextTable(columnNames, data);                                                         
tt.printTable();   

API juga memungkinkan pengurutan dan penomoran baris ...

daniel_or_else
sumber
1
Ini agak sulit untuk digunakan, tetapi ini lebih baik daripada terus-menerus menyesuaikan pemformatan string. Akan lebih baik lagi jika: - botol sumber diterbitkan ke repo Maven - dalam repo terkenal seperti Central
Greg Chabala
15

Saya telah membuat proyek yang dapat membangun tampilan tabel yang lebih canggih. Jika Anda ingin mencetak tabel, lebar tabel akan memiliki batas. Saya telah menerapkannya di salah satu proyek saya sendiri untuk mendapatkan cetakan faktur pelanggan. Berikut adalah contoh tampilan cetak.

           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            

Ini adalah kode untuk tampilan cetak di atas dan Anda dapat menemukan perpustakaan (Wagu) di sini .

CLOUGH
sumber
1
Mr. @CLOUGH, saya sangat menghargai jawaban Anda. ini cara yang bagus untuk menghasilkan faktur .. saya juga mengerjakan proyek tetapi saya tidak ingin bagian RETURNING DETAIL di faktur saya ... dapatkah Anda membantu saya melalui ini .. Saya tidak dapat memotong bagian ini
Rafi Abro
1
@ LZH - Ya, ini berfungsi dengan baik. Tapi, Anda perlu mengubah jenis huruf dari TextArea ke Monospace .
CLOUGH
1
Apakah itu dipublikasikan ke repositori pusat maven?
Hubbitus
1
Apakah Anda berencana melakukan itu?
Hubbitus
1
@Hubbitus, Sebenarnya saya berencana untuk memprogram ulang logika perpustakaan ini. Setelah semua itu, saya akan menerbitkan ini di maven.
CLOUGH
15

Saya mungkin sangat terlambat untuk Jawabannya tetapi di sini solusi sederhana dan umum

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));
    }
}

Dengan Output semacam ini

+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+
|                   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  |
+----------------------------------------+----------------------------------------+----------------------------------------+----------------------------------------+
Naval Kishore
sumber
Impor yang Anda butuhkan hanyalah: import java.util.HashMap; import java.util.List; import java.util.Map;
Jake Hm
Tidak buruk jika Anda bisa menyediakan main void statis publik dengan contoh aktual.
mmm
1
Solusi ini tidak bisa disebut "sederhana"
Gauraang Khurana
11

Lihat ini. Penulis memberikan solusi sederhana namun elegan yang tidak memerlukan pustaka pihak ketiga. http://www.ksmpartners.com/2013/08/nicely-formatted-tabular-output-in-java/

Contoh TableBuilder dan contoh keluaran

Mingjiang Shi
sumber
Solusi ini saya sangat baik menggunakan perpustakaan pihak ke-3: Apache Lang Tapi tetap solusi terbaik untuk kebutuhan saya. 1+
Spenhouet
Menyalin kode tersesat dari internet sebenarnya sedikit lebih buruk daripada perpustakaan pihak ketiga; ini adalah pustaka yang bahkan tidak seorang pun repot-repot mengemasnya untuk digunakan kembali oleh orang lain.
Greg Chabala
7

Karena sebagian besar solusi agak ketinggalan jaman, saya juga dapat menyarankan asciitable yang sudah tersedia di maven ( de.vandermeer:asciitable:0.3.2) dan dapat menghasilkan konfigurasi yang sangat rumit.

Fitur (menurut offsite):

  • Tabel teks dengan beberapa fleksibilitas untuk aturan dan konten, perataan, format, pengisi, margin, dan bingkai:
  • menambahkan teks, sesering yang diperlukan dalam berbagai format (string, penyedia teks, penyedia render, ST, cluster),
  • menghilangkan semua spasi kosong yang berlebihan (tabulator, blanko ekstra, kombinasi carriage return dan line feed),
  • 6 perataan teks yang berbeda: kiri, kanan, tengah, rata, baris terakhir kiri, kanan baris terakhir,
  • lebar fleksibel, disetel untuk teks dan dihitung dengan berbagai cara untuk rendering
  • karakter padding untuk padding kiri dan kanan (dapat dikonfigurasi secara terpisah)
  • karakter bantalan untuk bantalan atas dan bawah (dapat dikonfigurasi secara terpisah)
  • beberapa opsi untuk menggambar kisi
  • aturan dengan gaya berbeda (seperti yang didukung oleh tema kisi yang digunakan: normal, ringan, kuat, berat)
  • margin atas / bawah / kiri / kanan di luar bingkai
  • konversi karakter menjadi teks yang dihasilkan cocok untuk proses selanjutnya, misalnya untuk LaTeX dan HTML

Dan penggunaannya masih terlihat mudah:

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.
Hubbitus
sumber
2
Perpustakaan yang bagus dan terdokumentasi dengan baik
David Lilljegren
5
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));
 }
}

perbedaan ukuran input tidak mempengaruhi output

manoj jangam
sumber