有什么办法来从对象(Python的/红宝石/的Java / C#)表?
我想以编程方式创建一个简单的表。 我有一些对象,我想一些映射属性,头和收集到的行。
为什么要降价? 因为我想在以后手动编辑该文件。 眼下,整个过程是这样的:
- 报告引擎是在C#
- 有从其中产生DOCX对象(有中间XML或类似的东西)
- 几乎都是我必须做轻微的修复和我都开在MS Word是DOCX文档
- 它的麻烦,要求开发商团队来解决每一个错误,因为他们根本没有时间去做瞬间,我不得不等待下一个版本。
我已经想通了,如果我会得到降价的文件,我可以很容易地编辑,插入一些变量和使用pandoc给定的数据替换这些变量。 但是,要降价我必须知道如何在开发者可能产生降价表。
我需要做的只是生成Doxygen的降价表一样的东西,所以我想我会分享。 我已经在这两个的Python 2.7和3.3成功运行示例代码,虽然我不能要求我严格测试它。
# Generates tables for Doxygen flavored Markdown. See the Doxygen
# documentation for details:
# http://www.doxygen.nl/manual/markdown.html#md_tables
# Translation dictionaries for table alignment
left_rule = {'<': ':', '^': ':', '>': '-'}
right_rule = {'<': '-', '^': ':', '>': ':'}
def evalute_field(record, field_spec):
"""
Evalute a field of a record using the type of the field_spec as a guide.
"""
if type(field_spec) is int:
return str(record[field_spec])
elif type(field_spec) is str:
return str(getattr(record, field_spec))
else:
return str(field_spec(record))
def table(file, records, fields, headings, alignment = None):
"""
Generate a Doxygen-flavor Markdown table from records.
file -- Any object with a 'write' method that takes a single string
parameter.
records -- Iterable. Rows will be generated from this.
fields -- List of fields for each row. Each entry may be an integer,
string or a function. If the entry is an integer, it is assumed to be
an index of each record. If the entry is a string, it is assumed to be
a field of each record. If the entry is a function, it is called with
the record and its return value is taken as the value of the field.
headings -- List of column headings.
alignment - List of pairs alignment characters. The first of the pair
specifies the alignment of the header, (Doxygen won't respect this, but
it might look good, the second specifies the alignment of the cells in
the column.
Possible alignment characters are:
'<' = Left align (default for cells)
'>' = Right align
'^' = Center (default for column headings)
"""
num_columns = len(fields)
assert len(headings) == num_columns
# Compute the table cell data
columns = [[] for i in range(num_columns)]
for record in records:
for i, field in enumerate(fields):
columns[i].append(evalute_field(record, field))
# Fill out any missing alignment characters.
extended_align = alignment if alignment != None else []
if len(extended_align) > num_columns:
extended_align = extended_align[0:num_columns]
elif len(extended_align) < num_columns:
extended_align += [('^', '<')
for i in range[num_columns-len(extended_align)]]
heading_align, cell_align = [x for x in zip(*extended_align)]
field_widths = [len(max(column, key=len)) if len(column) > 0 else 0
for column in columns]
heading_widths = [max(len(head), 2) for head in headings]
column_widths = [max(x) for x in zip(field_widths, heading_widths)]
_ = ' | '.join(['{:' + a + str(w) + '}'
for a, w in zip(heading_align, column_widths)])
heading_template = '| ' + _ + ' |'
_ = ' | '.join(['{:' + a + str(w) + '}'
for a, w in zip(cell_align, column_widths)])
row_template = '| ' + _ + ' |'
_ = ' | '.join([left_rule[a] + '-'*(w-2) + right_rule[a]
for a, w in zip(cell_align, column_widths)])
ruling = '| ' + _ + ' |'
file.write(heading_template.format(*headings).rstrip() + '\n')
file.write(ruling.rstrip() + '\n')
for row in zip(*columns):
file.write(row_template.format(*row).rstrip() + '\n')
这里有一个简单的测试案例:
import sys
sys.stdout.write('State Capitals (source: Wikipedia)\n\n')
headings = ['State', 'Abrev.', 'Capital', 'Capital since', 'Population',
'Largest Population?']
data = [('Alabama', 'AL', '1819', 'Montgomery', '1846', 155.4, False,
205764),
('Alaska', 'AK', '1959', 'Juneau', '1906', 2716.7, False, 31275),
('Arizona', 'AZ', '1912', 'Phoenix', '1889',474.9, True, 1445632),
('Arkansas', 'AR', '1836', 'Little Rock', '1821', 116.2, True,
193524)]
fields = [0, 1, 3, 4, 7, lambda rec: 'Yes' if rec[6] else 'No']
align = [('^', '<'), ('^', '^'), ('^', '<'), ('^', '^'), ('^', '>'),
('^','^')]
table(sys.stdout, data, fields, headings, align)
给出了这样的输出:
State Capitals (source: Wikipedia)
| State | Abrev. | Capital | Capital since | Population | Largest Population? |
| :------- | :----: | :---------- | :-----------: | ---------: | :-----------------: |
| Alabama | AL | Montgomery | 1846 | 205764 | No |
| Alaska | AK | Juneau | 1906 | 31275 | No |
| Arizona | AZ | Phoenix | 1889 | 1445632 | Yes |
| Arkansas | AR | Little Rock | 1821 | 193524 | Yes |
Doxygen的呈现此为:
我不得不产生降价编程了一个要求, 最近的一个项目 ,所以我建立了一个图书馆,并张贴在GitHub上。 我们希望,你会发现它是有用的。
该项目被称为MarkdownLog ,它是一个轻量级(即最小的相关),便携式.NET库(PCL),可以从.NET数据结构,如集合和字典产生降价。 我用它记录的内部程序数据结构用于诊断目的,但它应该满足您的需求也。
下面是一个降价表是从集合来构建:
var data = new[]
{
new{Year = 1991, Album = "Out of Time", Songs=11, Rating = "* * * *"},
new{Year = 1992, Album = "Automatic for the People", Songs=12, Rating = "* * * * *"},
new{Year = 1994, Album = "Monster", Songs=12, Rating = "* * *"}
};
Console.Write(data.ToMarkdownTable());
// Produces:
//
// Year | Album | Songs | Rating
// ----:| ------------------------ | -----:| ---------
// 1991 | Out of Time | 11 | * * * *
// 1992 | Automatic for the People | 12 | * * * * *
// 1994 | Monster | 12 | * * *
请注意,当这个输出与GitHub的味降价解析器解析它会产生一个HTML表格。
默认情况下,列是基于其数据类型对齐(数字是右对齐,字符串左对齐)和标题名称是从对象的属性名称产生的。 如果这不是你想要的东西,有一些覆盖,使您可以输出更多的控制。
还有的建在所有支持标准的降价因素 ,也GFM表 。 我还补充说,我需要一些额外的元素类型(条形图,iOS版的UITableView),其被实现为代码块 ,使他们仍然坚持降价标准。
我是最近才上载的代码,GitHub上,因此文档基本现在。 话虽如此,有很多项目的单元测试,这应该证明它是如何工作负载。
我很欣赏它已经有一段时间,因为这个问题被问,但我希望这个项目将是对某人有用。