易于在 Swift 中打印文本表格。灵感来源于 Python 的 tabulate 库。
此软件包是为以下 Swift 版本编写和测试的
Apple Swift 版本 5.0
使用 Swift Package Manager 安装 TextTable
作为您项目的依赖项。
dependencies: [
.package(
url: "https://github.com/cfilipov/TextTable",
.branch("master"))
]
首先,导入 TextTable
import TextTable
在所有示例中,将使用以下数据结构
struct Person {
let name: String
let age: Int
let birhtday: Date
}
假设我们有一个 Person
集合,我们希望将其显示为表格。
let data = [
Person(name: "Alice", age: 42, birhtday: Date()),
Person(name: "Bob", age: 22, birhtday: Date()),
Person(name: "Eve", age: 142, birhtday: Date())
]
为您希望打印为表格的类型配置 TextTable
实例。最小配置将需要将值映射到您类型的列。
let table = TextTable<Person> {
[Column("Name" <- $0.name),
Column("Age" <- $0.age),
Column("Birthday" <- $0.birhtday)]
}
<-
运算符只是语法糖。如果您不想使用该运算符,可以使用带标签的参数代替。
let table = TextTable<Person> {
[Column(title: "Name", value: $0.name),
Column(title: "Age", value: $0.age),
Column(title: "Birthday", value: $0.birhtday)]
}
只需调用 print()
方法,传入 Person
的集合。
table.print(data)
Name Age Birthday
----- --- -------------------------
Alice 42 2016-08-13 19:21:54 +0000
Bob 22 2016-08-13 19:21:54 +0000
Eve 142 2016-08-13 19:21:54 +0000
您也可以通过调用 string(for:)
方法来获取渲染后的表格字符串。
let s = table.string(for: data)
您可以选择使用 style:
参数指定表格样式。
table.print(data, style: Style.psql)
+-------+-----+---------------------------+
| Name | Age | Birthday |
+-------+-----+---------------------------+
| Alice | 42 | 2016-08-13 08:12:58 +0000 |
| Bob | 22 | 2016-08-13 08:12:58 +0000 |
| Eve | 142 | 2016-08-13 08:12:58 +0000 |
+-------+-----+---------------------------+
在使用 string(for:)
方法时也可以指定样式。
let s = table.string(for: data, style: Style.psql)
有关支持样式的完整列表,请参见下方的支持的样式。
您可以为每列指定一个 Formatter。在此示例中,使用 DateFormatter 来自定义 Birthday
列的显示。
let df = DateFormatter()
dateFormatter.dateStyle = .medium
let table = TextTable<Person> {
[Column("Name" <- $0.name),
Column("Age" <- $0.age),
Column("Birthday" <- $0.birhtday, formatter: df)]
}
table.print(data, style: Style.psql)
+-------+-----+--------------+
| Name | Age | Birthday |
+-------+-----+--------------+
| Alice | 42 | Aug 13, 2016 |
| Bob | 22 | Aug 13, 2016 |
| Eve | 142 | Aug 13, 2016 |
+-------+-----+--------------+
默认情况下,TextTable 将计算每列所需的宽度。您也可以使用 width:
参数显式设置宽度。
let table = TextTable<Person> {
[Column("Name" <- $0.name, width: 10),
Column("Age" <- $0.age, width: 10)]
}
table.print(data, style: Style.psql)
+------------+------------+
| Name | Age |
+------------+------------+
| Alice | 42 |
| Bob | 22 |
| Eve | 142 |
+------------+------------+
某些表格样式可能包含内容左侧和/或右侧的填充,宽度参数不影响此填充。
默认情况下,如果指定了宽度并且列的内容比宽度更宽,则文本将在尾部被截断(.tail
截断模式)。
let table = TextTable<Person> {
[Column("Name" <- $0.name, width: 4), // defaults to truncation: .tail
Column("Age" <- $0.age)]
}
table.print(data, style: testStyle)
+------+-----+
| Name | Age |
+------+-----+
| Ali… | 42 |
| Bob | 22 |
| Eve | 142 |
+------+-----+
您还可以通过为 truncation:
参数指定 .head
来在文本字符串的头部截断。如果不存在 width
参数,则 truncation
参数无效。
let table = TextTable<Person> {
[Column("Name" <- $0.name, width: 4, truncate: .head),
Column("Age" <- $0.age)]
}
table.print(data, style: testStyle)
+------+-----+
| Name | Age |
+------+-----+
| …ice | 42 |
| Bob | 22 |
| Eve | 142 |
+------+-----+
如果您希望在列的内容不符合指定的宽度时触发致命错误,则可以指定 .error
截断模式。
let table = TextTable<Person> {
[Column("Name" <- $0.name, width: 4, truncate: .error),
Column("Age" <- $0.age)]
}
table.print(data, style: testStyle)
// fatal error: Truncation error
默认情况下,所有列都将左对齐。您可以单独设置每列的对齐方式。
let table = TextTable<Person> {
[Column("Name" <- $0.name), // default: .left
Column("Age" <- $0.age, align: .right)]
}
table.print(data, style: Style.psql)
+-------+-----+
| Name | Age |
+-------+-----+
| Alice | 42 |
| Bob | 22 |
| Eve | 142 |
+-------+-----+
默认情况下,TextTable 将计算未使用 width:
列参数指定显式宽度的每列的必要宽度。此计算通过迭代表格的每一行两次来完成:第一次计算最大宽度,第二次实际渲染表格。对于非常大的表格,此计算的开销可能不合适。如果您希望避免此计算,则必须为每列指定宽度。
在下面的示例中,table1
将产生宽度计算的开销,因为其中一列没有显式宽度。另一方面,table2
不会产生开销,因为所有列都具有显式宽度。
// This will still result in extra calculations
let table1 = TextTable<Person> {
[Column("Name" <- $0.name),
Column("Age" <- $0.age, width: 10)]
}
// This will skip the width calculations
let table2 = TextTable<Person> {
[Column("Name" <- $0.name, width: 9),
Column("Age" <- $0.age, width: 10)]
}
TextTable 支持与 tabulate 大部分相同的样式。
table.print(data, style: Style.plain)
Name Age Birthday
Alice 42 8/13/16
Bob 22 8/13/16
Eve 142 8/13/16
simple
是默认样式。它对应于 Pandoc Markdown 扩展中的 simple_tables
。
table.print(data) // or:
table.print(data, style: Style.simple)
Name Age Birthday
----- --- --------
Alice 42 8/13/16
Bob 22 8/13/16
Eve 142 8/13/16
grid
遵循 Emacs 的 table.el package 的约定。它对应于 Pandoc Markdown 扩展中的 grid_tables
。
table.print(data, style: Style.grid)
+-------+-----+----------+
| Name | Age | Birthday |
+=======+=====+==========+
| Alice | 42 | 8/13/16 |
+-------+-----+----------+
| Bob | 22 | 8/13/16 |
+-------+-----+----------+
| Eve | 142 | 8/13/16 |
+-------+-----+----------+
table.print(data, style: Style.fancyGrid)
╒═══════╤═════╤══════════╕
│ Name │ Age │ Birthday │
╞═══════╪═════╪══════════╡
│ Alice │ 42 │ 8/13/16 │
├───────┼─────┼──────────┤
│ Bob │ 22 │ 8/13/16 │
├───────┼─────┼──────────┤
│ Eve │ 142 │ 8/13/16 │
╘═══════╧═════╧══════════╛
table.print(data, style: Style.psql)
+-------+-----+----------+
| Name | Age | Birthday |
+-------+-----+----------+
| Alice | 42 | 8/13/16 |
| Bob | 22 | 8/13/16 |
| Eve | 142 | 8/13/16 |
+-------+-----+----------+
pipe
遵循 PHP Markdown Extra extension 的约定。它对应于 Pandoc 中的 pipe_tables
。此样式使用冒号来指示列对齐方式。
table.print(data, style: Style.pipe)
| Name | Age | Birthday |
|:------|----:|---------:|
| Alice | 42 | 8/13/16 |
| Bob | 22 | 8/13/16 |
| Eve | 142 | 8/13/16 |
org
遵循 Emacs org-mode 的约定。
table.print(data, style: Style.org)
| Name | Age | Birthday |
|-------+-----+----------|
| Alice | 42 | 8/13/16 |
| Bob | 22 | 8/13/16 |
| Eve | 142 | 8/13/16 |
rst
遵循 reStructuredText 样式的简单表格的约定。
table.print(data, style: Style.rst)
===== === ========
Name Age Birthday
===== === ========
Alice 42 8/13/16
Bob 22 8/13/16
Eve 142 8/13/16
===== === ========
html
生成 HTML 表格 标记。
table.print(data, style: Style.html)
<table>
<tr>
<th style="text-align:left;">Name</th>
<th style="text-align:center;">Age</th>
<th style="text-align:right;">Birthday</th>
</tr>
<tr>
<td>Alice</td>
<td>42</td>
<td>8/14/16</td>
</tr>
<tr>
<td>Bob</td>
<td>22</td>
<td>8/14/16</td>
</tr>
<tr>
<td>Eve</td>
<td>142</td>
<td>8/14/16</td>
</tr>
</table>
table.print(data, style: Style.latex)
\begin{tabular}{lll}
\hline
Name & Age & Birthday \\
\hline
Alice & 42 & 8/13/16 \\
Bob & 22 & 8/13/16 \\
Eve & 142 & 8/13/16 \\
\hline
\end{tabular}
您可以通过遵循 TextTableStyle
协议来创建自定义表格样式。
enum MyCustomStyle: TextTableStyle {
// implement methods from TextTableStyle...
}
extension Style {
static let custom = MyCustomStyle.self
}
table.print(data, style: Style.custom)
更改列表可以在 CHANGELOG 中找到。
提供类似用途的其他 Swift 库。
MIT 许可证
版权所有 (c) 2016 Cristian Filipov
特此授予许可,免费向任何获得本软件和相关文档文件(“软件”)副本的人员授予许可,以处理本软件,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售本软件副本的权利,并允许向为此目的提供本软件的人员提供以下条件
上述版权声明和本许可声明应包含在本软件的所有副本或主要部分中。
本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于适销性、特定用途的适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权诉讼或其他诉讼中,由本软件或本软件的使用或其他交易引起、产生或与之相关。