Print clojure maps as a human-readable table.
Add the latest version of library to your app.
For leiningen or boot:
[com.joshuadavey/crockery "<version>"]}
or, for deps.edn:
{com.joshuadavey/crockery {:mvn/version "<latest version>"}}
Require crockery.core, which contains the primary API:
(require '[crockery.core :as crockery])
The examples that follow use this data:
(def people
  [{:first-name "Alice", :last-name "Anderson", :age 32, :dues "98.00"}
   {:first-name "Bob", :last-name "Bobberson", :age 29, :dues "17"},
   {:first-name "Carol", :last-name "Carola", :age 26, :dues "105.50"},
   {:first-name "Doug", :last-name "Duggler", :age 41, :dues "0.125"}])
Print a table, inferring column names from the first map of the collection:
(crockery/print-table people)
|------------+-----------+-----+--------|
| First Name | Last Name | Age | Dues   |
|------------+-----------+-----+--------|
| Alice      | Anderson  | 32  | 98.00  |
| Bob        | Bobberson | 29  | 17     |
| Carol      | Carola    | 26  | 105.50 |
| Doug       | Duggler   | 41  | 0.125  |
|------------+-----------+-----+--------|
Or, specify the columns you want included:
(crockery/print-table [:age :last-name] people)
|-----+-----------|
| Age | Last Name |
|-----+-----------|
| 32  | Anderson  |
| 29  | Bobberson |
| 26  | Carola    |
| 41  | Duggler   |
|-----+-----------|
You can mix and match colspec forms (maps and keywords):
(crockery/print-table [{:name :last-name, :align :right} :first-name] people)
|-----------+------------|
| Last Name | First Name |
|-----------+------------|
|  Anderson | Alice      |
| Bobberson | Bob        |
|    Carola | Carol      |
|   Duggler | Doug       |
|-----------+------------|
In map form, most keys are optional, but a colspec must have at least :name or :key-fn and :title.
Use a keyword for both the getter function and the title of the column (titleized):
(crockery/print-table [{:name :age} {:name :last-name}] people)
|-----+-----------|
| Age | Last Name |
|-----+-----------|
| 32  | Anderson  |
| 29  | Bobberson |
| 26  | Carola    |
| 41  | Duggler   |
|-----+-----------|
Specify a different accessor function. It should be a function that takes one arg, and will be called for each "row" in the collection.
(crockery/print-table
 [{:title "Age (months)" :key-fn (comp (partial * 12) :age)}
  :first-name]
 people)
|--------------+------------|
| Age (months) | First Name |
|--------------+------------|
| 384          | Alice      |
| 348          | Bob        |
| 312          | Carol      |
| 492          | Doug       |
|--------------+------------|
Widths are normally calculated by finding the longest string per column, but you can also specify one:
(crockery/print-table [{:name :age, :width 10} {:name :last-name, :width 5}] people)
|------------+-------|
| Age        | Last  |
|------------+-------|
| 32         | Ander |
| 29         | Bobbe |
| 26         | Carol |
| 41         | Duggl |
|------------+-------|
Values that are too long will be truncated.
One of #{:left :center :right}, defaults to :left. Affects the data rows. When no :title-align is specified, also affects the header.
One special alignment, :decimal, attempts to line up the column so that the decimal point is in the same place in each row:
(crockery/print-table [:first-name :last-name {:name :dues :align :decimal}] people)
|------------+-----------+---------|
| First Name | Last Name | Dues    |
|------------+-----------+---------|
| Alice      | Anderson  |  98.00  |
| Bob        | Bobberson |  17     |
| Carol      | Carola    | 105.50  |
| Doug       | Duggler   |   0.125 |
|------------+-----------+---------|
Since numbers are printed as strings, in reality, the decimal alignment just looks for the first decimal point as an alignment anchor.
Provide your own header title rather than titleizing the :name parameter.
(crockery/print-table [:last-name {:name :first-name, :title "Given name"}] people)
|-----------+------------|
| Last Name | Given name |
|-----------+------------|
| Anderson  | Alice      |
| Bobberson | Bob        |
| Carola    | Carol      |
| Duggler   | Doug       |
|-----------+------------|
Same properties as :align, but only affects the header.
The default output format is an :org, which outputs an org-mode compatible table. There are other built-in formats that can be used. You can specify the format with the :format key in the options map, either before other arguments, or globally by rebinding the crockery.core/*default-options* var.
For each of these formats, the following colspec will be used:
(def colspec [:last-name
              {:name :first-name
               :title "Given name"
               :align :right}
              :age])
This is the default format. See any of the above examples.
A fixed-width, unadorned output format.
(crockery/print-table {:format :plain} colspec people)
Last Name  Given name  Age
Anderson        Alice  32 
Bobberson         Bob  29 
Carola          Carol  26 
Duggler          Doug  41 
(crockery/print-table {:format :simple} colspec people)
Last Name  Given name  Age
---------  ----------  ---
Anderson        Alice  32 
Bobberson         Bob  29 
Carola          Carol  26 
Duggler          Doug  41 
(crockery/print-table {:format :grid} colspec people)
+-----------+------------+-----+
| Last Name | Given name | Age |
+===========+============+=====+
| Anderson  |      Alice | 32  |
+-----------+------------+-----+
| Bobberson |        Bob | 29  |
+-----------+------------+-----+
| Carola    |      Carol | 26  |
+-----------+------------+-----+
| Duggler   |       Doug | 41  |
+-----------+------------+-----+
Another fixed-width format, with no surrounding border.
(crockery/print-table {:format :presto} colspec people)
 Last Name | Given name | Age 
-----------|------------|-----
 Anderson  |      Alice | 32  
 Bobberson |        Bob | 29  
 Carola    |      Carol | 26  
 Duggler   |       Doug | 41  
Based on the reStructured Text table format.
(crockery/print-table {:format :rst} colspec people)
=========  ==========  ===
Last Name  Given name  Age
=========  ==========  ===
Anderson        Alice  32 
Bobberson         Bob  29 
Carola          Carol  26 
Duggler          Doug  41 
=========  ==========  ===
This format uses unicode pipe characters. :fancy-grid is also available if you'd like separators between data rows.
(crockery/print-table {:format :fancy} colspec people)
┌───────────┬────────────┬─────┐
│ Last Name │ Given name │ Age │
├───────────┼────────────┼─────┤
│ Anderson  │      Alice │ 32  │
│ Bobberson │        Bob │ 29  │
│ Carola    │      Carol │ 26  │
│ Duggler   │       Doug │ 41  │
└───────────┴────────────┴─────┘
Like :fancy, but with bolder lines. :heavy-grid is also available if you'd like separators between data rows.
(crockery/print-table {:format :heavy} colspec people)
┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━┓
┃ Last Name ┃ Given name ┃ Age ┃
┣━━━━━━━━━━━╋━━━━━━━━━━━━╋━━━━━┫
┃ Anderson  ┃      Alice ┃ 32  ┃
┃ Bobberson ┃        Bob ┃ 29  ┃
┃ Carola    ┃      Carol ┃ 26  ┃
┃ Duggler   ┃       Doug ┃ 41  ┃
┗━━━━━━━━━━━┻━━━━━━━━━━━━┻━━━━━┛
Like :fancy, but with rounded corners. :rounded-grid is also available if you'd like separators between data rows.
(crockery/print-table {:format :rounded} colspec people)
╭───────────┬────────────┬─────╮
│ Last Name │ Given name │ Age │
├───────────┼────────────┼─────┤
│ Anderson  │      Alice │ 32  │
│ Bobberson │        Bob │ 29  │
│ Carola    │      Carol │ 26  │
│ Duggler   │       Doug │ 41  │
╰───────────┴────────────┴─────╯
Like :fancy, but with rounded corners. :double-grid is also available if you'd like separators between data rows.
(crockery/print-table {:format :double} colspec people)
╔═══════════╦════════════╦═════╗
║ Last Name ║ Given name ║ Age ║
╠═══════════╬════════════╬═════╣
║ Anderson  ║      Alice ║ 32  ║
║ Bobberson ║        Bob ║ 29  ║
║ Carola    ║      Carol ║ 26  ║
║ Duggler   ║       Doug ║ 41  ║
╚═══════════╩════════════╩═════╝
Like :fancy-grid, but with bolder separators between the header and body rows.
(crockery/print-table {:format :mixed-grid} colspec people)
┍━━━━━━━━━━━┯━━━━━━━━━━━━┯━━━━━┑
│ Last Name │ Given name │ Age │
┝━━━━━━━━━━━┿━━━━━━━━━━━━┿━━━━━┥
│ Anderson  │      Alice │ 32  │
├───────────┼────────────┼─────┤
│ Bobberson │        Bob │ 29  │
├───────────┼────────────┼─────┤
│ Carola    │      Carol │ 26  │
├───────────┼────────────┼─────┤
│ Duggler   │       Doug │ 41  │
┕━━━━━━━━━━━┷━━━━━━━━━━━━┷━━━━━┙
This tab-delimited format doesn't look great when printed directly, but is convenient for further processing with common unix utils. Alignment options are ignored.
(crockery/print-table {:format :tsv} colspec people)
Last Name	Given name	Age
Anderson	Alice	32
Bobberson	Bob	29
Carola	Carol	26
Duggler	Doug	41
Github-flavored Markdown (GFM) extends standard Markdown with a table syntax, including alignment designators.
(crockery/print-table {:format :gfm} colspec people)
| Last Name | Given name | Age |
|:----------|-----------:|:----|
| Anderson  |      Alice | 32  |
| Bobberson |        Bob | 29  |
| Carola    |      Carol | 26  |
| Duggler   |       Doug | 41  |
Copyright © 2021 Joshua Davey
Distributed under the Eclipse Public License version 1.0.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs | 
| ← | Move to previous article | 
| → | Move to next article | 
| Ctrl+/ | Jump to the search field |