2011-03-28 58 views
1

我一直在将列表报告转换为表格数据的工作,并且由于各种原因,我唯一的编程工具是groovy(即没有shell命令,没有C,没有perl的)。数据预先总结在五列中,分别为使用Groovy从表格报告创建数据表

分组(例如公司),小组(例如季度),小计,小组合计,总计(总结数据附加到第一行每个组):

Big Co.\t2009 Q4\t29\t88\t308 
\t2010 Q1\t38\t\t   
\t2010 Q4\t21\t\t   
Gargantua Inc.\t2009 Q4\t33\t139  
\t2010 Q1\t31\t\t   
\t2010 Q2\t36\t\t   
\t2010 Q3\t39\t\t   
Mediocre Ltd.\t2009 Q4\t39\t81  
\t2010 Q4\t42\t\t   

和输出需求是这样的:

<table> 
    <tr><th>Group</th><th>2009 Q4</th><th>2010 Q1</th><th>2010 Q2</th><th>2010 Q3</th><th>2010 Q4</th><th>Subtotal</th></tr> 
    <tr><th>Big Co</th><td>29</td><td>38</td><td>&nbsp;</td><td>&nbsp;</td><td>38</td><th>308</th></tr>  
    <tr><th>Gargantua Inc</th><td>29</td><td>31</td><td>36</td><td>39</td><td>&nbsp;</td><th>139</th></tr> 
    <tr><th>Gargantua Inc</th><td>39</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>42</td><th>81</th></tr> 
    <tr><th>&nbsp;</th><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><th>308</th></tr> 
</table> 

我希望能够运行一些环比数据;把东西粘到一个关联数组的关联数组中,在我去的时候创建一个完整的关键列表;然后再次循环以产生输出。我看了一下groovy,Map语法完全抛出。

任何人都可以指点一些更清晰的groovy Map迭代的例子,这样我至少可以用这个在水中弄到脚趾吗?

任何帮助感激地收到。

(如果有人认为这只是一个钓鱼之旅,我kludged在一起的PHP版本做的伎俩 - 基本上我需要能够转化为常规此...)

<?php 
$rows   = explode("\n", $data); 
$group   = ""; 
$subgroup  = ""; 
$table   = array(); 
$totals   = array(); 
$subgroup_names = array(); 
$group_names = array(); 
foreach($rows as $key => $row) { 
    $rowData = explode("\t", $row); 
    if($rowData[0]) { 
    $group = $rowData[0]; 
    $group_names[$rowData[0]] = true; 
    } 
    if($rowData[1]) { 
    $subgroup = $rowData[1]; 
    $subgroup_names[$rowData[1]] = true; 
    } 
    $table[$group][$subgroup]['jobcount'] = $rowData[2]; 
    if($rowData[3]) $totals[$group]['jobcount'] = $rowData[3]; 
    if($rowData[4]) $totals['grandtotal'] = $rowData[4]; 
} 
$group_names = array_keys($group_names); 
asort($group_names); 
$subgroup_names = array_keys($subgroup_names); 
asort($subgroup_names); 

$result = array(); 
$result['header'] = "<th>&nbsp;</th>"; 
foreach ($subgroup_names as $subgroup) { 
    $result['header'] .= "<th>$subgroup</th>"; 
} 
$result['header'] .= "<th>Subtotals</th>"; 

foreach ($group_names as $group) { 
    $result[$group] = "<th>$group</th>"; 
    foreach ($subgroup_names as $subgroup) { 
    $value = isset($table[$group][$subgroup]['jobcount'])? 
     $table[$group][$subgroup]['jobcount']: 
     '&nbsp;'; 
    $result[$group] .= "<td>".$value."</td>"; 
    } 
    $result[$group] .= "<th>".$totals[$group]['jobcount']."</th>"; 
} 

$result['footer'] = ""; 
foreach ($subgroup_names as $subgroup) { 
    $result['footer'] .= "<th>&nbsp;</th>"; 
} 
$result['footer'] .= "<th>Total</th>"; 
$result['footer'] .= "<th>".$totals['grandtotal']."</th>"; 

echo "<table><tr>".join($result, "</tr>\n<tr>")."</tr></table>"; 

?> 
+0

这是你的数据文件是如何?完全像你粘贴的第一个格式化的东西?即:大公司的数据分布在三条线上?并在每行的文本之前留出空格? – 2011-03-28 09:13:24

+0

是。 :-(就是这样......对于组中第一行的每个组的摘要数据,以及文件第一行的整个集合的摘要数据。不,真的。:-( – Dycey 2011-03-28 09:16:24

+0

实际上,空白区域可能是我的,但是在当前组中有一行标签,例如上面示例数据中的第2,3,5,6,7和9行 – Dycey 2011-03-28 09:21:21

回答

1

好,我知道了一起......这也许不是最漂亮的 - 但是也不是输入格式;-)

String txt = '''Big Co.\t2009 Q4\t29\t88\t308 
    \t2010 Q1\t38\t\t   
    \t2010 Q4\t21\t\t   
    Gargantua Inc.\t2009 Q4\t33\t139  
    \t2010 Q1\t31\t\t   
    \t2010 Q2\t36\t\t   
    \t2010 Q3\t39\t\t   
    Mediocre Ltd.\t2009 Q4\t39\t81  
    \t2010 Q4\t42\t\t''' 

// Parse the text 
def summary = txt.split('\n').inject([]) { list, row -> 
    def split = row.split('\t').collect { it.trim() } 
    while(split.size() < 5) split << '' 
    if(split[ 0 ]) { 
    list << [ group:split[ 0 ], grouptotal:split[ 3 ], grandtotal:split[ 4 ], subtotals:[:] ] 
    } 
    list[ -1 ].subtotals << [ (split[ 1 ]):split[ 2 ] ] 
    list 
} 

// Get a sorted set of all available quarters 
def allQuarters = summary.subtotals*.keySet().flatten() as TreeSet 

// Then build our html output 
def writer = new StringWriter() 
def builder = new groovy.xml.MarkupBuilder(writer) 
builder.table() { 
    // Header row 
    tr { 
    th "group" 
    allQuarters.each { q -> 
     th q 
    } 
    th "summary" 
    } 
    // Row for each group 
    summary.each { group -> 
    tr { 
     td group.group 
     allQuarters.each { q -> 
     def v = group.subtotals."$q" 
     if(v) 
      td v 
     else 
      td { mkp.yieldUnescaped '&nbsp;' } 
     } 
     td group.grouptotal 
    } 
    } 
    // Footer row 
    tr { 
    td { mkp.yieldUnescaped '&nbsp;' } 
    allQuarters.each { q -> 
     td { mkp.yieldUnescaped '&nbsp;' } 
    } 
    td summary.grandtotal.find { it } // Get the first non-empty grandtotal 
    } 
} 
println writer.toString() 
+0

Tim - 谢谢 - 它看起来像很好,而且相当广泛的groovy ;-)然而,一个轻微的问题 - 似乎抛出一个错误 – Dycey 2011-03-28 09:59:36

+0

groovy.lang.MissingMethodException:没有方法的签名:java.util.LinkedHashMap.leftShift()适用于参数类型:(java.util.LinkedHashMap)values:{[“2009 Q4”:“29”]} – Dycey 2011-03-28 10:00:08

+0

你正在运行的是什么版本的Groovy?我认为在版本1.7.2中添加了地图上的leftshift – 2011-03-28 10:06:25