所有
早上好!
我有一个excel文件,其数据如下所示,我试图使用POI解析
A
B
C
D1
D2
F
G1
G2
G3
M
S1
R
T
U
L
X
Y
Z
是否可以生成如下所示的输出
A
A-->B
A-->B-->C
A-->B-->C-->D1
A-->B-->C-->D2
A-->B-->F
A-->B-->F-->G1
A-->B-->F-->G2
A-->B-->F-->G3
A-->B-->M
A-->B-->M-->S1
A-->R
A-->R-->T
A-->U
L
L-->X
L-->X-->Y
L-->X-->Y-->Z
我已经尝试了很长一段时间,但还没有想出逻辑
由于
答案 0 :(得分:1)
使用Apache POI的Java解决方案:
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class ParseTreeDemo
{
private static final int NUM_COLUMNS = 4;
public static void main(String[] args)
{
try
{
FileInputStream file = new FileInputStream(new File("Test.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook(file);
XSSFSheet sheet = workbook.getSheetAt(0);
// Use a column marker to save the 'farthest' column so far
int currColMarker = -1;
List<String> list = new ArrayList<>();
//Iterate through each rows one by one
Iterator<Row> rowIterator = sheet.iterator();
while (rowIterator.hasNext())
{
Row row = rowIterator.next();
for(int currCol = 0; currCol < NUM_COLUMNS; currCol++)
{
Cell cell = row.getCell(currCol);
if(cell == null)
continue;
if(cell.getCellType() == Cell.CELL_TYPE_STRING) {
if(currCol > currColMarker) {
// A farther column, simply append and
// update column marker
currColMarker = currCol;
list.add(cell.getStringCellValue());
}
else if (currCol == currColMarker) {
// At same level as column marker
// Remove old value at same level, before appending
list.remove(list.size() - 1);
list.add(cell.getStringCellValue());
}
else {
// At a 'nearer' column, remove those values beyond
// this level before appending
currColMarker = currCol;
list = list.subList(0, currCol);
list.add(cell.getStringCellValue());
}
}
}
// For displaying the current contents
StringBuilder sb = new StringBuilder();
for(String s : list) {
if(sb.length() != 0) {
sb.append("-->");
}
sb.append(s);
}
System.out.println(sb.toString());
}
file.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
<强>输出:强>
A
A-->B
A-->B-->C
A-->B-->C-->D1
A-->B-->C-->D2
A-->B-->F
A-->B-->F-->G1
A-->B-->F-->G2
A-->B-->F-->G3
A-->B-->M
A-->B-->M-->S1
A-->R
A-->R-->T
A-->U
L
L-->X
L-->X-->Y
L-->X-->Y-->Z
想法:
注意:Test.xlsx
包含问题中所述的值。
答案 1 :(得分:0)
如果列出的数据位于名为data
的变量中,则以下内容将在Tcl中起作用:
proc merge {a b} {
set res {}
foreach ac [split $a {}] bc [split $b {}] {
if {![string is space $ac] && [string is space -strict $bc]} {
append res $ac
} else {
append res $bc
}
}
set res
}
set current {}
foreach line [split [string trim $data] \n] {
set current [merge $current [string trimright $line]]
puts [join $current -->]
}
我最初使用的是伪堆栈方法,但是&#34; merge&#34;具有累计行(current
)的每个新行,使得新行中的非空白文本将覆盖累积行中的文本,并且如果新行更短,则累计行将被截断(在修剪掉之后)尾随空格。)
一旦我有合并的行,我可以利用Tcl中的(大多数)字符串也是列表的事实,并将其打印为通过使用&#34; - &gt;&#加入单词而形成的字符串34;令牌。